12

Inspired by this video, I tested further with {}+[].

Test 1:

typeof {}+[]  //"object"

Okay, so {}+[] is an object.

Test 2:

var crazy = {}+[];
typeof crazy  //"string"

What? Didn't {}+[] is an object? Why is it a string now?

Test 3:

console.log({}+[])

What I got:

enter image description here

So it is a number!... No?

So what actually is the type of {}+[]??

UPDATED

To people who say {}+[] is a empty string:

{}+[] === ""     //false
({}+[]) === ""   //false
({};+[]) === ""  //SyntaxError
({}+[]).length   //15

JavaScript is so hard to understand...

Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
  • I think in test1, typeof finds first paramater's type -> {}, and it's an object, try `typeof ({}+[])` this one, it's string. – Okan Kocyigit Apr 29 '12 at 22:20
  • @pcamal, So is it a number or a string? (Thought `{}+[]` would be `object`, because both of them are.) – Derek 朕會功夫 Apr 29 '12 at 22:22
  • 1
    Regarding your update: `{}+[] === ""` is evaluated as `{}; +[] === "";`, i.e. empty block and `+[] === ""`. `{}+[] === 0` yields `true`. – Felix Kling Apr 29 '12 at 22:29
  • *JavaScript is so hard to understand*: Well, that's because you are ambiguous ;) When encountering `{}` in `{}+[] === ""` the parser does not know whether `{}` should indicate an object literal or a block. Since this is not in an expression context, `{}` is interpreted as block (the default behavior). The parenthesis `(...)` *force* an evaluation as expression. – Felix Kling Apr 29 '12 at 22:34
  • Maybe you are right... `{}+[]===({}+[]) //false` – Derek 朕會功夫 Apr 29 '12 at 22:36
  • Yep, this is evaluated as `{};+[]===({}+[])` which ends up being `{};0 === "[object Object]"`. If you want to learn more about how the addition operator works, have a look at the specification: http://es5.github.com/#x11.6.1 – Felix Kling Apr 29 '12 at 22:40
  • @FelixKling - But why it adds `;` after `{}`? – Derek 朕會功夫 Apr 29 '12 at 22:43
  • 2
    I just added this to indicate that the line `{}+[]` is interpreted as two statements and not as one. But since JavaScript has automatic semicolon insertion it might actually do this. Why? Because if some syntax is ambiguous, a decision has to be made how to interpret it. In this case, the developers decided to interpret `{}+[]` as `block`, `unary plus`, `array` and not as `object`, `addition operator`, `array`. You might not agree with this, but that's how it is :) – Felix Kling Apr 29 '12 at 22:50
  • possible duplicate of [What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wat' talk for CodeMash 2012?](http://stackoverflow.com/questions/9032856/what-is-the-explanation-for-these-bizarre-javascript-behaviours-mentioned-in-the) – Bergi Feb 16 '13 at 11:22

2 Answers2

13

Type of {}+[] may vary depending on the context.

  1. typeof {}+[] //"object"
    As per operators precedence in this case typeof {} evaluates to "object", +[] adds an empty string(array is coerced to string) therefore result is "object".
    You could think of checking typeof ({}+[]) (your second case).

  2. var crazy = {}+[]; typeof crazy //"string"
    In this case you are adding object and array - they both coerce to string, therefore typeof returns "string".

  3. {}+[]
    This is interpreted as an empty block of code, unary plus and empty array. First part does nothing, array is converted to a comma-separated string of it's elements(empty string for empty array), then to a number(empty string is converted to 0), hence 0.

UPDATED

  • {}+[] === "" //false
    see #3, {} is interpreted as a block, you are getting 0 on the left.
    Compare {}+[] === 0 // true.

  • ({}+[]) === "" //false
    see #1, {} is interpreted as an object literal. When trying to add array and object, they both convert to string, "[object Object]" for object and empty string for array. Hence, you are getting "[object Object]" on the left.
    Compare ({}+[]) === "[object Object]" // true.

  • ({};+[]) === "" //SyntaxError
    I guess, this one is self-explanatory :)

  • ({}+[]).length //15
    15 is exactly the length of "[object Object]", see above.

Li0liQ
  • 11,158
  • 35
  • 52
  • 4
    @Derek: Because `+""` is `0`. @Li0liQ: Btw, the string is *not* converted to a number equal to the length of the string. `+"abc"` returns `NaN`. How the unary plus converts strings is defined in the specification. – Felix Kling Apr 29 '12 at 22:25
  • Yep, and `({}+[])` in the console will give you object. – VisioN Apr 29 '12 at 22:28
  • @Felix Kling Thanks for the remark, indeed, array is converted to a comma-separated list of it's values or empty string in case of empty array. Empty string is converted to 0. – Li0liQ Apr 29 '12 at 22:30
0
var f = {}+[];
console.log(f==="[object Object]")

this will log true because when you assign {}+[] to the var it converts it to string by using the toString() method of it... which in this case returns "[object Object]" (which is 15 letters long - and that where the length=15 is from)

Yaron U.
  • 7,681
  • 3
  • 31
  • 45