3

In my Javascript console (in Chrome) I'm trying this:

 { 'a' : 1 }

and getting SyntaxError: Unexpected token :

But this works:

 ['a', 1]

What gives???

Alex D
  • 29,755
  • 7
  • 80
  • 126
  • Thanks to everybody for explaining... though I still consider this to be a defect in JavaScript. The places where a block can appear in the text of a valid JS program are completely different from the places where an object literal can appear, and the parser should easily be able to tell the difference. – Alex D Jun 29 '13 at 18:10

4 Answers4

7

It's because curly braces have two uses - either introducing a block, or as the start of an object literal (the latter being an expression).

The console can't tell which, so it assumes a statement block, and only later finds that the contents of the block can't be parsed as statements.

For array literals with square brackets that ambiguity doesn't exist.

The ambiguity can be resolved by changing the context so that the {...} must be interpreted as an expression rather than a statement block, e.g. by making it the RHS of an operator, wrapping it in parentheses, or passing it as a function parameter, etc.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
3

This is a block:

{
    var x = 'stuff'
    function doStuff(arg) { alert(arg) }
    doStuff(x)
}

It will alert stuff.

Now, about your example: JavaScript thinks it's a block, like this:

{
    'a' : 1
}

Since 'a' : 1 is not a valid statement, it fails.

Note that if you do

'x' + { 'a' : 1 }

It works, because there's no way a block could come after a +.

tckmn
  • 57,719
  • 27
  • 114
  • 156
2

You can do new Object({'a' : 1}) for that.

joakimdahlstrom
  • 1,575
  • 1
  • 11
  • 23
  • I wouldn't say it's incorrect if you COULD do it this way. But sure, there are other ways also. – joakimdahlstrom Jun 29 '13 at 18:50
  • It's also not a "good" way to do it. Best practices say that it's a bad idea to directly invoke primitive constructors (e.g. Object or Number) – Chris Hall Dec 16 '14 at 18:29
2

As others have pointed out, this is due to the fact that curly braces have dual use.

The easiest way to work around the ambiguity is by adding a pair of parentheses:

> {'a': 1}
SyntaxError: Unexpected token :

> ({'a': 1})
Object {a: 1}
NPE
  • 486,780
  • 108
  • 951
  • 1,012