简体   繁体   中英

js casting and type coercion - Why !!{}[true] is not true?

Typing in Chrome console:

{}[true]  // [true] (object)
!!{}[true] // false (boolean)

Why is !!{}[true] not true when {}[true] is?

How did you evaluate {}[true] ? Actually it's undefined since empty object doesn't have property named 'true' . And it's obvious that undefined is not true .

UPD : I've checked it in Google Chrome Developer Tools and...

{}[true] // [true]
!!{}[true] // false
console.log({}[true]) // undefined

The first line is [true] since there are 2 statements involved. The first one is an empty block ( {} ) and the second one is an array with one element (true). In contrast second line evaluates as expression (as well as the argument in the third one), to {} which here is no longer a block but an empty object.

Assuming these statements stand on their own:

{}[true] is interpreted as

{} // empty block
[true] // array literal expression

So if you type this in the console, the result of the last statement is printed, which is an array containing one element, the boolean value true .

!!{}[true] on the other hand is interpreted as accessing the property 'true' of an empty object. This will return undefined and is converted to false when cast to a boolean.

This depends on the context. When JavaScript parser sees {} at the begining it thinks its a block of code, not object, thus effectively {}[true] is the same as [true] and indeed, in console:

> {}[true]
[true]

but

> x = {}[true];
undefined

because {} is not at the begining or

> ({}[true])
undefined

because () forces JS to treat it like an expression.

If JavaScript parser sees something in front of {} it interprets {} as object, thus in console:

> !!{}[true]
true
 {}[true] => true (object) 

Not really a boolean object. If at all, it returns an array with one item - the boolean true. This happens when {} is interpreted as an (empty) block (see Why {} != ( {} ) in JavaScript? ), and the second statement [true] is an array literal. If you tried

({}[true])
// or
({})[true]

(or force it in some other way to be evaluated as an expression) you access the "true" property of an empty object which is undefined . This happens in your second case as well:

 !!{}[true] => false (boolean) 

as the !! coerces the {} to be interpreted as an object literal. And !undefined is true , so !!undefined will yield false .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM