0

Why is the result of the expression {}+[] 0?

It appears that the + is treated as a unary operator instead of a normal addition operator. The expression then becomes {}0. Why is this valid JavaScript and why is the result 0? Why is the object literal in the expression ({})+[] treated normally?

Note: I tried searching for a similar question in SO but it doesn't look like searching using symbols works.

halfer
  • 19,824
  • 17
  • 99
  • 186
nick zoum
  • 7,216
  • 7
  • 36
  • 80
  • 1
    Does this answer your question? [Objects and arrays addition](https://stackoverflow.com/questions/11930644/objects-and-arrays-addition) – austin wernli Feb 13 '20 at 22:34
  • https://2ality.com/2012/01/object-plus-object.html – Dai Feb 13 '20 at 22:34
  • Empty sets are `false` and `false` + `false` is `false`. Although after testing it i get `object Object`. – GetSet Feb 13 '20 at 22:35
  • Not sure what you could have searched for to get this, honestly. I know it's damn hard to find these sorts of things but I also know that the [Wat talk](https://www.destroyallsoftware.com/talks/wat) included this behaviour and it has a pretty good explanation here. That's how I found it. – VLAZ Feb 13 '20 at 22:37
  • After testing it i get `object Object`. `console.log({}+[]);` is *object Object*. ... `if ( {}+[] ) console.log("true");` outputs "true". – GetSet Feb 13 '20 at 22:43
  • @GetSet I was asking why `{} + []` is interpreted the same as `{}0` and `0`. It turns out it's because the `{}` is treated as a code block and not an object literal. You could write `{var x = 2;} + []` and it would work the same. – nick zoum Feb 13 '20 at 22:45
  • @GetSet you're changing the parsing result since you force `{}+[]` to be interpreted as an expression. You'd get the same result with `({}+[])`. The thing is that if you have `{}+[]` standalone, the `{}` is interpreted as an code block. Since there is nothing in it, it's an empty code block. So, the actual evaluation is just `+[]` - a unary plus with an empty array as operand. Casting an array to a number returns the length of the array which is zero. – VLAZ Feb 13 '20 at 22:47
  • @VLAZ If I state the `{}` as an object literal (i.e. `{"s":2}+[]`) why do I get `Uncaught SyntaxError: Unexpected token ':'`? Shouldn't the engine realize its an object and thus do `"[object Object]" + ""`? – nick zoum Feb 13 '20 at 22:49
  • @VLAX and nickzoum ... i see the difference now. Makes sense. And possibly `{}` returns null or undefined. – GetSet Feb 13 '20 at 22:49
  • @nickzoum because it's *still* treated as a code block. And you've just typed an invalid [label](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label) there. You can force the parser into expression mode by surrounding the whole thing in brackets. Fun fact [Chrome already does it for you](https://stackoverflow.com/questions/36438034/why-is-no-longer-nan-in-chrome-console?noredirect=1&lq=1). You can also see the same behaviour in the Node.js REPL where `{}+[]` will actually produce `"[object Object]"` (the string). – VLAZ Feb 13 '20 at 22:52
  • 1
    @GetSet no `{}` when in the beginning of the line literally does nothing. Returns nothing. It's just a way to mark a section of code - same as when you have `if (cond) {}` or `function() {}` - the curly brackets are code blocks. They don't produce a value. You can have a free code block, too but until ES6 that didn't really do anything. – VLAZ Feb 13 '20 at 22:53
  • @VLAZ completely logical once explained like that. I get it. – GetSet Feb 13 '20 at 22:55
  • @VLAZ Why is the `{}` in `{} + {}` automatically surrounded by `()` in chrome but in `{} + []` it's not? – nick zoum Feb 13 '20 at 23:00
  • @nickzoum weird. OK, that's new to me. It definitely used to treat `{} + []` as `({} + [])`. Perhaps they've changed the behaviour again. `{}` does get treated as `({})` - it produces an object. So...I don't know what `{} + []` breaks out of the behaviour. I know I *have* seen some expressions that don't get auto-wrapped in brackets, since that would actually lead to different behaviour. For example `(var x = 1)` produces a syntax error but there are more subtle ones. Can't remember a specific example, though. I don't know when that changed in Chrome but it's different than before. – VLAZ Feb 13 '20 at 23:06

0 Answers0