3

Typing in Chrome console:

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

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

sanchez
  • 4,519
  • 3
  • 23
  • 53

4 Answers4

8

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.

Artem Sobolev
  • 5,891
  • 1
  • 22
  • 40
  • 1
    @san.chez, if we assume `{}` to be an object, then yes, it is. If we assume it as just javascript code, then it doesn't have any value since there are two statements (javascript doesn't have any last-statement-value-is-result-of-statement-list feature yet). – Artem Sobolev Apr 10 '13 at 12:03
7

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.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
4

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
freakish
  • 54,167
  • 9
  • 132
  • 169
3
{}[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.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375