Why is it that !!0 is false and {}+[] is 0 but !!({}+[]) is true?

时间:2015-07-31 19:40:50

标签: javascript

Just tried this in my browser's console:

!!0 //=> false
{} + [] //=> 0
!!({} + []) //=> true

What's going on here!?

Edit: I'm talking about {} + [](object first) which is different from [] + {}(array first), the latter always returns 0. Spacing ({}+[] vs {} + []) doesn't seem to matter

3 个答案:

答案 0 :(得分:6)

Doing ({} + []) produces the string [object Object] which when coerced into a boolean is a true value.

Why it treats it as a string concatenation when wrapped in parentheses and a number when not wrapped, I'm trying to figure out.

Update: I think I've figured it out. This trick happens when the code at a global level, i.e. not as an assignment or as an argument. What's probably happening is it's interpreting the {} as a block rather than an object.

If you type { var x = 4; } +[] into your console you'll get the same result as {}+[]. Where as if you place it inside of a set of parentheses it forces the compiler to interpret the interior as an expression i.e. an Object plus an Array which produces the string.

My guess is this change is due in part to the change in scope handling due to let.

答案 1 :(得分:1)

{} + [] // 0
!!0 // false

({} + []) // [object Object]
!!({} + []) // true

eval("{} + []") // 0
!!eval("{} + []") // false

Nothing wrong here! But there is one really weird thing: if you put ({}+[]) === {}+[], the answer is true, and if you put {}+[] === ({}+[]), the answer is false, wtf.

答案 2 :(得分:-2)

That's wrong, {} + [] is not 0:

alert({} + []);

Update: not commutative behaviour (Node shell):

// as expected
{} + [] // '[object Object]'
[] + {} // '[object Object]'

// however
eval("{} + []") // 0
eval("[] + {}") // '[object Object]'