admin管理员组文章数量:1195770
I was expecting JavaScript to reject objects with duplicated properties as invalid but it accepts them in some cases.
{"a":4,"a":5}
results in an SyntaxError
at least in Firefox and Chrome which seems obvious due to the property a
being defined twice.
However ({"a":4,"a":5})
evaluates just fine and results in an object {"a":5}
in both Firefox and Chrome.
Why is the expression with the parenthesis accepted?
Summing up the responses: The first example is simply not the construction of an object but a block of labeled statements. Duplicated properities in objects are perfectly valid in which case the last definition wins.
Thanks a lot for your answers!
I was expecting JavaScript to reject objects with duplicated properties as invalid but it accepts them in some cases.
{"a":4,"a":5}
results in an SyntaxError
at least in Firefox and Chrome which seems obvious due to the property a
being defined twice.
However ({"a":4,"a":5})
evaluates just fine and results in an object {"a":5}
in both Firefox and Chrome.
Why is the expression with the parenthesis accepted?
Summing up the responses: The first example is simply not the construction of an object but a block of labeled statements. Duplicated properities in objects are perfectly valid in which case the last definition wins.
Thanks a lot for your answers!
Share Improve this question edited Nov 8, 2012 at 11:23 Augustus Kling asked Nov 8, 2012 at 9:26 Augustus KlingAugustus Kling 3,3331 gold badge23 silver badges25 bronze badges 3 |6 Answers
Reset to default 5It is perfectly legal in ECMAScript 3 to declare duplicate properties in an object literal; the SyntaxError
you get probably comes from the fact that you used an object literal as a statement, which is not possible due to the confusion with block statements ({ doSomething(); }
).
If you want this to be reported as an error, you may want to switch to ECMAScript 5's strict mode: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode.
What you state has no problem if you assign it to a variable, if you don't however, you get the error you mention. Which makes all the difference from a syntax point of view.
When you wrap any structure in parens you are causing that syntax to be evaluated as an expression, the result of which is stored as a temporary variable. The error I get when not doing so in Firefox is unexpected label or invalid label, so it seems without assignment, or parens, this object construction is not treated as an object construction - instead it is treated as a block with multiple label statements that are defined illegally:
{
a: function(){
alert('a');
},
b: function(){
alert('b');
}
}
The above should be totally acceptable as an object, however you get a similar error if you evaluate it without assinging it to some form of variable, or evaluating it with parens. Put simply the duplication of the attribute name is not causing the error :)
Basically imagine your first example, but like this:
function (){
"a": 4,
"b": 5
}
That is roughly how these browsers are treating it, which is now obviously illegal javascript syntax... whereas it wasn't so obvious before.
In the first notation (parentheses-less) the javascript syntax is ambiguous. From ecmascript specification:
An ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block.
A block basically evaluates all the statements inside, equivalent to evaluating "a":4,"a":5
which is not valid JS and, in fact, returns the same SyntaxError Unexpected token :
Wrapping that code in parentheses (or, rather, a grouping operator) removes that ambiguity since an assignment expression cannot be followed by a block statement:
var test = {"a":"a","a":"b"}; //test.a === "b"
Furthermore this ambiguity can be removed by any operator or expression that cannot be used with a block statement. A practical scenario hardly comes to mind, maybe if you wanted to return an object literal as part of a conditional operator?
//this *could* come out of a JS minifier:
return x ? (foo(),{"a":"b"}) : (bar(), {"b":"a"});
Why should it not be accepted? You're simply overwriting the values. I think it's rather a feature, than an error. And it works fine for me on various browsers: http://jsbin.com/oculon/1/edit It's like writing
var a;
a = 4;
a = 5;
alert(a);
it's not Error you just overwrite value with another
I'm guessing (though not certain) that this evaluates as an error because of the difference between the way Firefox and Chrome's JS parsers treat statements and expressions. So because it's wrapped in parentheses the second time, it's considered an expression. Since it's looking for less information in an expression, it can ignore erroneous values. You'll see that if you do...
var a = {'a': 5, 'a': 4};
console.log(a);
It works fine! And also notice that here it's in the right hand side of the statement, giving a hint that it's an expression.
本文标签: Why is object with duplicated property accepted in JavaScriptStack Overflow
版权声明:本文标题:Why is object with duplicated property accepted in JavaScript? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738526509a2092772.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
a
– elclanrs Commented Nov 8, 2012 at 9:33console.log
argument list removes the syntactic ambiguity that was causing the error in the first place – Oleg Commented Nov 8, 2012 at 11:38SyntaxError
is thrown? I can't get it to throw in any circumstance. – Zamicol Commented Sep 13, 2022 at 16:55