不寻常的对象定义

时间:2016-06-11 10:28:31

标签: javascript

我偶然发现了这个奇怪的物体声明。

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

它有效,但我猜它不会。

困惑我在Chrome DevTools中打开控制台,然后输入:

var a = {};
// => undefined

到目前为止没什么奇怪的。但后来我输入:

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

好的,嗯......这不应该起作用吗?另一种尝试,没有单独评估报表:

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

嗯,没有抛出SyntaxError。如果我评估一下,我可以看到它按照我的意图定义。

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

发生了什么事?我试图谷歌它,但我不知道要搜索什么,我缺乏某种知识来弄清楚发生了什么。有人可以解释一下吗?

2 个答案:

答案 0 :(得分:5)

在代码中,

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

第二个{}内的代码只是一个块中的语句。 该块用于对多个语句进行分组,并且是有效的语法,因此不会引发错误。

代码相当于

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

执行块内的代码,config对象为

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

执行程序段后。

使用对象文字语法来代替使用上述语法,更好地定义对象。

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

与代码相同

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

相当于

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

可以写成

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

来自MDN Docs

  

阻止声明(或其他语言的复合声明)用于对零个或多个语句进行分组。该块由一对花括号分隔。

  

{ a.b = 'b'; }抛出未捕获的SyntaxError:意外的令牌。

如果未声明变量a,则会抛出错误。

答案 1 :(得分:1)

补充以前的说法..

在JavaScript中,这是一个对象文字:

{x: 3}

这是一个块:

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

任何陈述都可以进入一个区块。

麻烦的是,{x: 3}通常会被解释为一个块。

要使它成为JavaScript的对象文字,你必须用括号括起来:

({x: 3})

当Chrome DevTools看到您的输入是一个未被包围的对象字面时,它就是什么。它会将{x: 3}变为({x: 3}){y: 15, z: 'kar'}变为({y: 15, z: 'kar'}),依此类推。

麻烦的是,它也会对块执行此操作。它将{x = y}变为({x = y}),这当然是语法错误。 JavaScript认为你给它一个对象字面值,所以它不会期望一个声明。

但是,如果在对象文字之前有一个语句,DevTools完全忽略了将未加括号的对象文字转换为带括号的对象文字的规则。所以这有效:

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

声明并非 在块之前实际上只需要一个分号:

;{x = y}

这只是Chrome DevTools的奇怪怪癖。它应该帮助那些刚接触JavaScript(和对象文字)编码的人,但对于 经验丰富的人来说可能会有点混乱!