为什么JavaScript中接受具有重复属性的对象?

为什么JavaScript中接受具有重复属性的对象?,javascript,Javascript,我希望JavaScript拒绝具有重复属性的对象,因为它们是无效的,但在某些情况下它会接受它们 {“a”:4,“a”:5}导致至少在Firefox和Chrome中出现语法错误,这似乎很明显,因为属性a被定义了两次 然而,({a:4,“a:5})的计算结果很好,在Firefox和Chrome中都会产生一个对象{a:5} 为什么接受带括号的表达式 总结回答:第一个示例不是对象的构造,而是一组标记语句。对象中的重复属性完全有效,在这种情况下,最后一个定义获胜 非常感谢你的回答 为什么不接受?您只是在覆

我希望JavaScript拒绝具有重复属性的对象,因为它们是无效的,但在某些情况下它会接受它们

{“a”:4,“a”:5}
导致至少在Firefox和Chrome中出现
语法错误
,这似乎很明显,因为属性
a
被定义了两次

然而,
({a:4,“a:5})
的计算结果很好,在Firefox和Chrome中都会产生一个对象
{a:5}

为什么接受带括号的表达式

总结回答:第一个示例不是对象的构造,而是一组标记语句。对象中的重复属性完全有效,在这种情况下,最后一个定义获胜


非常感谢你的回答

为什么不接受?您只是在覆盖这些值。我认为这是一个特征,而不是一个错误。它在各种浏览器上对我来说都很好: 就像写作一样

var a;

a = 4;
a = 5;

alert(a);

在ECMAScript 3中,在对象文本中声明重复属性是完全合法的;您得到的
SyntaxError
可能是因为您使用了对象文字作为语句,这是不可能的,因为与块语句(
{doSomething();}
)混淆


如果您希望将其报告为错误,您可能需要切换到ECMAScript 5的严格模式:。

这不是错误,您只需使用另一个值覆盖该值,如果您将该值分配给变量,您所声明的内容没有问题,但如果您不这样做,则会得到您提到的错误。从语法的角度来看,这是完全不同的

当您在parens中包装任何结构时,您将使该语法作为表达式进行计算,其结果存储为临时变量。当我在Firefox中不这样做时,我得到的错误是意外标签无效标签,因此似乎没有赋值或参数,此对象构造不被视为对象构造-而是被视为包含非法定义的多个label语句的块:

{
  a: function(){
    alert('a');
  },
  b: function(){
    alert('b');
  }
}
作为一个对象,上面的内容应该是完全可以接受的,但是,如果您对它进行求值时没有将其赋给某种形式的变量,或者使用parens对其进行求值,则会得到类似的错误。简单地说,属性名称的重复不会导致错误:)

基本上想象一下您的第一个示例,但如下所示:

function (){
  "a": 4,
  "b": 5
}
这大概就是这些浏览器对待它的方式,这显然是非法的javascript语法。。。然而,这在以前并不明显。

我猜(虽然不确定)这是一个错误,因为Firefox和Chrome的JS解析器处理语句和表达式的方式不同。因为第二次是用括号括起来的,所以它被认为是一个表达式。由于它在表达式中查找的信息较少,因此可以忽略错误的值。你会看到如果你这样做

var a = {'a': 5, 'a': 4};
console.log(a);
很好用!还请注意,它位于语句的右侧,提示它是一个表达式。

在第一个表示法(无括号)中,javascript语法不明确。发件人:

ExpressionStatement不能以大括号开头 因为这可能会使它与块不明确

A基本上计算内部的所有语句,相当于计算无效JS的
“A”:4,“A”:5
,实际上返回相同的语法错误
意外标记:

将该代码包装在括号中(或者更确切地说)可以消除这种歧义,因为赋值表达式后面不能跟block语句:

var test = {"a":"a","a":"b"}; //test.a === "b"
此外,任何不能与block语句一起使用的运算符或表达式都可以消除这种歧义。如果您想返回一个对象文字作为条件运算符的一部分,那么很难想到一个实际的场景

//this *could* come out of a JS minifier:
return x ? (foo(),{"a":"b"}) : (bar(), {"b":"a"});

在FF和Chrome上使用和不使用括号似乎都可以正常工作。很好,我的意思是它返回最后一个
a
@elclanrs:这是一个误导性的结果(我之前在jsfiddle上也是这么认为的:)-将有问题的代码放在
控制台中。log
参数列表删除了有趣的内容,但是,在ECMAScript 6的严格模式下,重复的属性名是完全可以的。人们注意到,在事先不知道属性名的情况下,编写没有语法错误的对象文字有点棘手。