Created
January 12, 2019 17:29
-
-
Save 1kohei1/aad4f876f7189343d42f4e5c02611966 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
JSON.stringify(undefined); // undefined | |
JSON.stringify(function() {}); // undefined | |
JSON.stringify([1, undefined, function() {}, 4]); // "[1,null,null,4]" | |
JSON.stringify({a: 2, b: function() {}}); // "{"a":2}" | |
// The second argument is called a replacer. It filters out which will be in stringified JSON | |
var a = { | |
a: 1, | |
b: 2, | |
c: 3, | |
} | |
JSON.stringify(a, ['a', 'b']); // "{"a":1,"b":2}" | |
// If an array is passed, it recursively checks if the key is in array | |
JSON.stringify(a, (k, v) => { | |
if (['a','b', ''].indexOf(k) >= 0)) { | |
return v; | |
} | |
}) // "{"a":1,"b":2}" | |
// If the second argument is a function, it receives a key and the value. Return the value if it's in the stringified format. Return undefined if not. The first time is called with the object itself, and the k will be an empty string. After that, k and v are called recursively. | |
// The third argument is the "space". It defines an indentation. | |
JSON.stringify(a, null, 2); | |
// "{ | |
// "a": 1, | |
// "b": 2, | |
// "c": 3 | |
// }" | |
/****** ToNumber ******/ | |
Number([1,2,3]); // NaN | |
Number([1]); // 1 | |
Number(['-12']); // -12 | |
Number([]); // 0 | |
Number(''); // 0. In other languages, this throws an error. | |
Number(undefined); // NaN | |
Number(null); // 0 | |
// It first uses valueOf. If it doesn't exist or not return the primitive, it goes toString(). If toString() could not provide a primitive, it results TypeError | |
a = { valueOf: function() { return "42"; } }; | |
b = { toString: function() { return "42"; } }; | |
c = [4, 2]; | |
c.toString = function() { return this.join('') }; // "42" | |
Number(a); // 42. valueOf() is used | |
Number(b); // 42 toString() is used | |
Number(c); // 42 toString() is used | |
a = { | |
valueOf: () => 'a', | |
toString: () => 12, | |
} | |
Number(a); // NaN. As long as the primitive is returned, the conversion happens. | |
Number([""]); // [""].valueOf() => [""]. It's not pritmitive. [""].toString() => "". Number("") => 0 | |
Number(["0"]); // 0 | |
Number(["-0"]); // -0 | |
Number([null]); // 0/ [null].valueOf() => [null]. [null].toString() => "" | |
Number([undefined]); // 0 | |
Number([1,2,3]); // NaN | |
Number([[[]]]); // 0 | |
// The difference between parseInt and Number | |
var a = "42"; | |
var b = "42px"; | |
Number(a); // 42 | |
parseInt(a); // 42 | |
Number(b); // NaN | |
parseInt(b); // 42 | |
// for parseInt, it returns the result up to the point it was able to parse. | |
var c = 'a12'; | |
Number(c); // NaN | |
parseInt(c); // NaN | |
// If there is nothing it can parse, it will return NaN as well | |
var d = '1a2d'; | |
Number(d); // NaN | |
parseInt(d); // 1 | |
parseInt(NaN); // NaN | |
parseInt(Infinity); // NaN | |
parseInt(-Infinity); // NaN | |
// Cannot handle Infinity. | |
/****** Implicit coercion ******/ | |
var a = '42'; | |
var b = '0'; | |
var c = 42; | |
var d = 0; | |
a + b; // "420" | |
c + d; // 42 | |
a + c; // "420" | |
b + d; // "420" | |
So one of the operands is applied to the string, it will be coerced to the string! | |
c + 1 + a; // (42 + 1 + '42') => "4342" | |
// It first sums by the number and then coerce them to the string! | |
a = [1, 2]; | |
b = [3, 4]; | |
a + b; // 1,23,4 | |
// Here, if anything other than string is passed, it first tries to coerces to the string. If either operand becomes string, it performs string concatenation. Otherwise, it does numeric addition. | |
a = 42; | |
a + ''; // "42" | |
a = "3.14" | |
a - 0; // 3.14 | |
// || and && doesn't result the boolean value. | |
// They select only one of operands | |
var a = 42; | |
var b = 'abc'; | |
var c = null; | |
a || b; // 42 | |
a && b; // "abc" | |
c || b; // "abc" | |
c && b; // null | |
// The same rule applies to Python and Ruby | |
// For ||, if the first argument is true, it uses it. If the first argument is false, it uses the second argument. no matter what | |
// undefined || 0; // 0 | |
// For &&, if the first argument is false, uses. If the argument is true, it uses the second operands. | |
1 && 2; // 2 | |
null && 2; // null | |
var foo = '123'; | |
if (foo == true) { | |
console.log('123'); // This doesn't print out. WHY!? | |
} | |
// This is because double coercion compares the number! | |
// So look at these | |
if (1 == true) { | |
console.log('abc'); // abc | |
} | |
if ('1' == true) { | |
console.log('abc'); // abc | |
} | |
if ('00001' == true) { | |
console.log('abc'); // abc | |
} | |
if ('00001 ' == true) { | |
console.log('abc'); // abc | |
} | |
// Another example | |
var foo = []; | |
if (foo) { | |
console.log('abc'); // "abc" This is exepcted. | |
} | |
if (foo == false) { | |
- console.log('xyz'); // "xyz" WHAT?y | |
} | |
// == allows coercion in the equality comparison and === disallows coercion. | |
// How can this make evaluated to be true? | |
if (a == 2 && a == 3) { | |
console.log('true!'); | |
} | |
// Easy, you need to modify the valueOf() function | |
var i = 2; | |
Number.prototype.valueOf = function() { return i++; }; | |
var a = new Number(42); | |
if (a == 2 && a == 3) { | |
console.log('true!'); // Now this prints out! | |
} | |
// Relational comparison (> and <) | |
// First, it calls ToPrimitive. If they are not the string, values are coerced to number and compared numerically |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment