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 {}
.