javascriptsyntaxobject-literal

Why do object literals sometimes need to be wrapped in parentheses when evaluated in an interactive console?


I am kinda lost on why the following code does what it does the way it does.

For the following expression I would expect 1 as result, since on the right side of a literal we actually have an obj.

Expression:

> { a : 1 }.a 

result Chrome:

Syntax error: Unexpect token .

result NodeJS

1

(Another question: why nodejs and chrome differs on this (and on the following))

While the expression itself has a syntax error assigning it to a variable still works.

> var x = { a : 1 }.a; x;

result:

1

Now using eval around the expression does work in Chrome and in NodeJS

> eval({ a : 1 }.a)

result Chrome and Node

1

Now using eval and the string based expression neither platform works

eval("{ a : 1 }.a")

result Chrome:

SyntaxError: Unexpected token >

result NodeJS:

... //REPL waits more code

And finally the parenthesis solves it all but why?

> eval("({ a : 1 }.a)")

Solution

  • eval takes a string, so calling eval({ a : 1 }.a) is the same as eval("1").

    In statement context, {} delimit a block, not an object literal. You can go in expression context by using () as a grouping operator.

    So:

    { a : 1 }.a
    

    Is actually a block, label, numeric literal and dot-access on nothing:

    {
       a:  1
    }
    
    .a
    

    Node REPL actually runs in an expression context to begin with, but that's unusual. They run your code like eval("(" + replInput + ")")