Johan Jonasson
Johan Jonasson

Reputation: 534

Unusual object definition

I stumbled upon this, to my eyes, strange object declaration.

var config = {};
{ 
  config.foo = 'foo';
  config.bar = 'bar';
};

It works, though I would have guessed it wouldn't.

Confused I open up the console in Chrome DevTools, and enter:

var a = {};
// => undefined

Nothing strange so far. But then I enter:

{ a.b = 'b'; }
// => Uncaught SyntaxError: Unexpected token .

Ok, hmm ... wasn't this supposed to work? Another try, without separate evaluations of the statements:

var a = {}; {a.b = 'b'};
// => "b"

Hmm, no SyntaxError thrown. And if I evaluate a, I can see it is defined as I intended.

a;
// => Object {b: "b"}

What is happening? I've tried to google it, but I don't know what to search for, and I lack some kind of knowledge to figure out what is happening. Can someone please explain it?

Upvotes: 2

Views: 86

Answers (2)

Nebula
Nebula

Reputation: 7151

To add on to what has previously been said..

In JavaScript, this is an object literal:

{x: 3}

And this is a block:

{
  console.log("Hello, world!");
}

Any statement can go inside of a block.

The trouble is, {x: 3} will normally be interpreted as a block, on its own.

To make it an object literal as far as JavaScript is concerned, you have to surround it in parenthesis:

({x: 3})

That's what Chrome DevTools does whenever it sees that your input is an object literal that isn't surrounded. It'll make {x: 3} into ({x: 3}), {y: 15, z: 'kar'} into ({y: 15, z: 'kar'}), and so on.

The trouble is, it'll also do this for blocks. It turns {x = y} into ({x = y}), which is of course a syntax error. JavaScript thinks you're giving it an object literal, so it doesn't expect a statement.

However, DevTools completely ignores the rule of turning un-parenthesized object literals into parenthesized object literals if you have a statement before the object literal. So this works:

console.log('Bananas!'); {x = y}

And the statement doesn't really need to be a statement. There actually just needs to be a semicolon before the block:

;{x = y}

It's just a weird quirk of Chrome DevTools. It's supposed to help people new to coding with JavaScript (and object literals), but it can be slightly confusing to people that are experienced!

Upvotes: 1

Tushar
Tushar

Reputation: 87203

In the code,

var config = {};
{ 
  config.foo = 'foo';
  config.bar = 'bar';
};

The code inside second { and } is just statements grouped in a block. The block is used to group multiple statements and is valid syntax so, no error is thrown.

The code is equivalent to

var config = {};
config.foo = 'foo';
config.bar = 'bar';

The code inside the block is executed and the config object is

{foo: "foo", bar: "bar"}

after the execution of the block.

Instead of using the above syntax, it's better to use object literal syntax to define an object.

var config = {
    foo: 'foo',
    bar: 'bar
};

Same with the code

var a = {}; {a.b = 'b'};

Which is equivalent to

var a = {};
a.b = 'b';

and can be written as

var a = {
    b: 'b';
};

From MDN Docs

A block statement (or compound statement in other languages) is used to group zero or more statements. The block is delimited by a pair of curly brackets.


{ a.b = 'b'; } throws Uncaught SyntaxError: Unexpected token .

This will throw error if variable a is not declared.

Upvotes: 5

Related Questions