I was watching this talk, and on 16:34 there is a javascript coercion test:
5 - "4" // 1
5 + "4" // 54
+!{}[true] // 1
+[1] // 1
+[1, 2] // NaN
7 - "a" // NaN
7 / 0 // Infinity
What is the exact logic behind those calculations?
5 - "4" // 1
The -
operator coerces its operands to numbers. See the subtraction operator and the abstract ToNumber operation it uses.
5 + "4" // 54
When either operand is a string, the +
is string concatenation, not addition, and the other operand is coerced to string if necessary. See the addition operator and the abstract ToPrimitive and ToString operations.
+!{}[true] // 1
Explaining this is pointless. Don't do that in your code.
Oh, okay:
{}[true]
is evaluated first. The true
is coerced to "true"
(via ToString linked above) because it's used in a property accessor and isn't a Symbol. {}
is an empty object, so {}[true]
is undefined
, leaving us with +!undefined
.!undefined
is true
, because it coerces undefined
to a boolean via the abstract ToBoolean operation, and then negates that to get true
.+true
is 1, because of ToNumber linked above.+[1] // 1
[1]
is an array with a 1
in it. Applying +
to it runs it through ToPrimitive
, which ultimate ends up being [1].join(",")
, giving us..."1"
. +"1"
is 1 thanks to ToNumber.
+[1, 2] // NaN
Almost exactly like the above, but since the string "1,2"
can't be completely parsed as a number, we get NaN
.
7 - "a" // NaN
Almost exactly like our first example. ToNumber("a")
is NaN
, and any calculation involving NaN
(such as substraction) results in NaN
.
7 / 0 // Infinity
In JavaScript, division by 0 is defined as Infinity; see the Applying the / Operator.
As you can see, these are all understandable, with effort, by referring to the specification. Some are tricky, but really the tricky ones are things you'd almost never run into in the real world.