Why do the following computations in Javascript give these results?
{} + []
0
[] + {}
"[object Object]"
{} + {}
NaN
[] + []
""
What is going on?
Why do the following computations in Javascript give these results?
{} + []
0
[] + {}
"[object Object]"
{} + {}
NaN
[] + []
""
What is going on?
Although it looks like all of your examples are using the addition operator, in fact half of them are using the addition operator (the binary +
), and half are using the unary +
operator.
These are using the addition operator:
[] + {}
[] + []
and these are using the unary +
operator:
{} + []
{} + {}
Let's start with the first two:
[] + {}
[] + []
The JavaScript addition operator is defined in terms of strings (concatenation) and numbers (addition), and so when its operands are not strings or numbers, it coerces them to be.
Full details in the specification, but basically: First both arguments are converted to primitives via the abstract ToPrimitive operation, which may result in any of several primitive types (string, number, boolean). Then if either operand is a string, the other operand is coerced to be a string and concatenation is done. If not, both are coerced to numbers and addition is carried out.
So if you play with Number({})
and String({})
and Number([])
and String([])
, you'll see what's going on.
Now, let's look at the other two:
{} + []
{} + {}
These are really tricky because they look like addition, but they aren't: They're an empty block followed by an expression using the unary +
operator. When expecting either a statement or expression, if the parser sees {}
, it processes it as a block statement. Since those blocks are empty, they don't do anything at all and we're left with:
+ []
+ {}
That ends up coercing the array or object to a number. Number([])
is 0
, and Number({})
is NaN
.
If we force the parser to expect just an expression (perhaps by using ()
), not either an expression or statement, we see a different result because we're back to the addition operator:
({} + [])
"[object Object]"
{} + {}
"[object Object][object Object]"