4
votes

What are the values of []+[], []+{}, {}+[], {}+{}? And How?

This my console log

>{} + {}
>NaN
>[] + []
>''
>{} + []
>0
>[] + {}
>[Object object]

Also

>var a = [] + {}
>a
>[Object object]
>var b = {} + []
>b
>[Object object]

How did the value change on assignment?

SRC: video

2
those are just caveat's there aren't any design reasons for thisJoseph Le Brech

2 Answers

11
votes

The difference for the {} + [] is that when you do an assignment it is parsed in an expression context but when you type it by itself it is parsed as a statement

var b = /*an expression*/

This distinction is visible when using anonymous functions

//expression
var f = function(){}; //allowed

//statement
function(){}; //not allowed. function statements need a name.

So in the expression context, we add {} (empty object) and [] (empty list) with the binary + operator. Due to the type conversion rules, {} is converted to the string "[object Object]" and [] is converted to the empty string, the concatenation of which is "[object Object]" too.

//parenthesis force an expression 
({} + "hello")  //"[object Object]hello"
({} + [])       //"[object Object]"
({} + [1])      //"[object Object]1"
({} + [1,2])    //"[object Object]1,2"

Meanwhile, when we remove the parenthesis, the {} is parsed as an empty block statement. For pratical purposes it works as if we had commited it entirely, leaving an unary + operator to act on the list. This converts it to a number.

+[]     // 0
{} + [] // 0
+{}     // NaN
{} + {} // NaN
{} +"17"// 17

While it might seem weird to be able to get a value from a statement (instead of only from expressions), the Javascript standard, does specify a value for a statement. In our case, our program is a list of two source elements, whose value is given by the last statement, an expression statement.

A way to see the statement completion value in action is via eval:

 eval("{}")  //undefined
 eval("1")   //1
 eval("1;2") //2
4
votes

The + operator concats strings. So it attempts to convert the objects and arrays to strings.

{} converts to '[Object object]', and [] converts to ''.

EDIT: I can't explain why {} + [] is 0 and why ({}) + [] is "[object Object]".