Object Plus Array Is Not Zero

Exploring a common Javascript misconception with Chrome and ASTExplorer

Evin Sellin
4 min readMar 16, 2021

You may have seen Gary Bernhardt’s WAT talk in which he pulls out these confusing lines of JavaScript:

{} + []
0
[] + {}
"[object Object]"

He shows the audience that an object plus an array is 0, but an array plus an object is [object Object]”. Lo and behold, if you try this in the chrome console, that’s what you’ll get:

But something’s a little fishy about that claim. If you wrap these lines in parentheses, you can see that both of these lines evaluate identically:

The same, just like the spec said!

So what’s going on? Let’s take a look at the abstract syntax tree to see if there’s anything weird going on syntactically.

If we plug {} + [] into ASTExplorer, we get this:

Source: ASTExplorer.net

An empty block, followed by a unary (+) operator? That’s not Object plus Array! That’s… something else entirely.

To confirm our suspicions, we see that Javascript’s unary + operator acting on an array evaluates to 0, showing us that our interpretation is indeed correct. The empty code block is evaluated as a noop, and all we’re left with is the unary expression:

To double-check, we go to ASTExplorer again to make sure that [] + {} is actually adding an array to an object like we expect:

Yep! Our understanding looks good here! So, if we’re confused by syntax, plug it into ASTExplorer, and everything will be revealed, right? Right?

And back into weirdness

The story, however, is incomplete. Remember how we pasted something into ASTExplorer to see how it parsed, and then pasted it into the Chrome console to see how it behaved? Let’s try this same process out with regular JavaScript objects.

Chrome does what we expect and creates an object:

When we paste it into ASTExplorer, however, we get the following:

Token (1:8) refers to the colon

What? Why does ASTExplorer think that it’s a syntax error? We’re declaring an object! This is like 1st day of JavaScript stuff! How can ASTExplorer not catch that?

So it turns out ASTExplorer is actually right here, and Chrome is the one behaving weirdly. A bare object, outside of any other statement, will not be parsed as a bare object, but instead a code block, exactly like before! Since the inner contents of the code block do not parse as a statement, parsing fails, leading to a syntax error on the colon.

We can convince ourselves that that’s true with a quick eval:

Why does Chrome console end up creating an object when provided with a clear syntax error?

Chrome does this because when you paste something into the Chrome console, you instinctively have 2 different behavioral expectations:

  1. The Chrome console evaluates statements.
  2. Pasting an expression into the Chrome console should evaluate that expression

These two expectations are fundamentally in conflict with one another, and can’t be reconciled. They lead to a fundamental contradiction in how a bare object should be parsed.

To try to bridge this gap, Chrome dynamically figures out whether to parse a line as a Statement or an Expression. As an Expression, the line ends up evaluating to an object, but as a Statement, the line ends up in a syntax error. Chrome has changed the exact rules they use here over time, but the one they’ve landed on seems to be this behavior:

  1. See if the input starts with a { and ends with a }
  2. If not, parse the input as a series of statements.
  3. If so, try to parse the input as an expression.
  4. If that fails, fall back to parsing the input as a series of statements.

I’m about 90% sure that’s where it stands today, but I also haven’t checked in like a year, and I’m not about to dig into the Chrome source to figure it out again.

In summary:

  • Object plus Array is not 0, even though it sure looks like it is in the Chrome console
  • You should use ASTExplorer if you’re confused about syntax
  • The Chrome console is a great way to evaluate statements and expressions, but…
  • The Chrome console has a few narrow gotchas.
  • If you’re confused, a quick eval will tell you the source of truth.

Evin Sellin is an enthusiastic programmer that might not exist. He possibly enjoys programming language trivia, topics in machine learning, and writing semi-useless articles about technology.

--

--