The accepted answer is not correct (it is now, though), see this example:
if([5] == true) {
console.log("hello");
}
If everything is indeed processed as the accepted answer states, then [5] == true
should have evaluated to true
as the array [5]
will be converted to its string counterpart ("5"
), and the string "5"
is truthy (Boolean("5") === true
is true
), so true == true
must be true.
But this is clearly not the case because the conditional does not evaluate to true
.
So, what's actually happening is:
1. ![]
will convert its operand to a boolean and then flip that boolean value, every object is truthy, so ![]
is going to evaluate to false
.
At this point, the comparison becomes [] == false
2. What gets into play then is these 2 rules, clearly stated in #6 in the specs for the Abstract Equality Comparison algorithm:
- If Type(x) is boolean, return the result of the comparison ToNumber(x) == y.
- If Type(y) is boolean, return the result of the comparison x == ToNumber(y)
At this point, the comparison becomes [] == 0
.
3. Then, it is this rule:
If Type(x) is Object and Type(y) is either String or Number,
return the result of the comparison ToPrimitive(x) == y.
As @Jonas_W stated, an array's ToPrimitive
will call its toString
, which will return a comma-separated list of its contents (I am oversimplifying).
At this point, the comparison becomes "" == 0
.
4. And finally (well, almost), this rule:
If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x) == y.
An empty string converted to a number is 0
(Number("") == 0
is true
).
At this point, the comparison becomes 0 == 0
.
5. At last, this rule will apply:
If Type(x) is the same as Type(y), then
.........
If Type(x) is Number, then
.........
If x is the same Number value as y, return true.
And, this is why the comparison evaluates to true
. You can also apply these rules to my first example to see why it doesn't evaluate to true
.
All the rules I quoted above are clearly stated here in the specs.