1

I've been fiddling with JavaScript, and I found some behavior I don't understand. The problem seems to be with automatic semicolon insertion (ASI), but, to me, it looks like ASI is misbehaving. The following code has been tested with node v8.10, and with Google Chrome's developer tools' console (Version 73.0.3683.86 (Official Build) (64-bit)).

> 0 == {}
false
> {} == 0
...

The three dots mean Uncaught SyntaxError: Unexpected token == (taken from chrome's developer tool's console output.) It seems to be explained by ASI actually turning it into {;} == 0, but from reading the specs (linked above), it shouldn't do that. Did I misunderstand the specs?

There are some funny situations that this causes, and some weird ones too. For example, {} + 4 evaluates to 4, because it is {;} + 4, or simply +4. But, 4 + {} is '4[object Object]'. And, weirdly:

> {} + 4 + {}
'[object Object]4[object Object]'

It didn't become {;} + 4 + {}, which would be the same as 4 + {}, now it actually accepted the first {} as an object instead of a block!! The right-most token matters:

> {} + 4 + {} + 4
'4[object Object]4'

Now, the first {} was interpreted as an empty block again. Furthermore,

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

The second line's behavior seems to be ASI again, because +{}, or Number({}), evaluates to NaN (The first {} is interpreted as an empty block again.)

extra funny code:

> {a:3}.a + 2
... // Uncaught SyntaxError: Unexpected token .
> ({a:3}.a + 2)
5

This time, the first one actually becomes an empty block with the label a!

I expected no ASI to happen in those examples, since it should already be (I think) a valid production of the grammar. And it seems weird how we can keep alternating the right-most token ({} + 4 + {} and {} + 4 + {} + 4) and it changes the meaning of the first {}.

Pedro Queiroga
  • 381
  • 1
  • 12
  • 1
    I don't see how this is connected to ASI. The fact that `{} + 4` evaluates to 4 is I believe because the engine treats `{}` not as an empty object literal, but as empty "code block", so it's basically interpreted as `+4`, that is `4`. (This is certainly the reason for the much-mocked behaviour whereby `{} + []` evalutes to 0 whereas `[] + {}` is `"[object Object]"`). But this doesn't explain why `{} == 0` is a syntax error, I thought the engine would treat `{}` as an empty object in cases like this where treating it as a code block makes no sense. – Robin Zigmond Apr 11 '19 at 22:53
  • @RobinZigmond Yes, I may have crowded my text too much, but I said exactly the first thing you said! As for the second part, `{} == 0`, I think it becomes `{;} == 0`, the same way `{} + 4` does. I addressed this, too, and it is why I think it is connected to ASI. I also thought it would be treated as an empty object, especially because the current behavior makes ASI actually create a nonexistent error, instead of taking one out. – Pedro Queiroga Apr 11 '19 at 23:02
  • I understand now why you say it might not be ASI. I assumed it was, because of it being interpreted as an empty block and throwing an error, even if it should try the empty object (which wouldn't throw an error)... But since ASI already put a semicolon there, it can't be an empty object anymore, which would explain empty object not even being considered when parsing the code. But I might have made a wrong assumption! – Pedro Queiroga Apr 11 '19 at 23:17

0 Answers0