15

重複したプロパティを持つオブジェクトをJavaScriptが無効として拒否することを期待していましたが、場合によってはそれらを受け入れます。

{"a":4,"a":5}SyntaxError少なくともFirefoxとChromeでは、プロパティaが2回定義されているため、明らかな結果になります。

ただし、正常に評価され、FirefoxとChromeの両方({"a":4,"a":5})でオブジェクトが生成されます。{"a":5}

括弧付きの表現が受け入れられるのはなぜですか?

応答の要約:最初の例は、単にオブジェクトの構築ではなく、ラベル付けされたステートメントのブロックです。オブジェクト内の重複したプロパティは完全に有効です。この場合、最後の定義が優先されます。

ご回答ありがとうございます!

4

6 に答える 6

5

ECMAScript 3では、オブジェクトリテラルで重複するプロパティを宣言することは完全に合法です。おそらく、SyntaxErrorオブジェクトリテラルをステートメントとして使用したという事実から得られますが、これはブロックステートメント()との混同のために不可能{ doSomething(); }です。

これをエラーとして報告したい場合は、ECMAScript 5の厳密モードに切り替えることをお勧めします:https ://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode 。

于 2012-11-08T09:41:50.933 に答える
4

変数に割り当てても問題はありませんが、割り当てないと、前述のエラーが発生します。これは、構文の観点からすべての違いを生みます。

構造体を括弧で囲むと、その構文が式として評価され、その結果が一時変数として格納されます。Firefoxでそうしないと発生するエラーは、予期しないラベルまたは無効なラベルであるため、割り当てまたは親子関係がないように見えます。このオブジェクト構造はオブジェクト構造として扱われません。代わりに、複数のラベルステートメントを持つブロックとして扱われます。違法に定義された:

{
  a: function(){
    alert('a');
  },
  b: function(){
    alert('b');
  }
}

上記はオブジェクトとして完全に受け入れられるはずですが、何らかの形式の変数に割り当てたり、parensで評価したりせずに評価すると、同様のエラーが発生します。簡単に言えば、属性名の重複はエラーを引き起こしていません:)

基本的にあなたの最初の例を想像してください、しかしこのように:

function (){
  "a": 4,
  "b": 5
}

これは、これらのブラウザがそれをどのように扱っているかを大まかに示しています。これは、明らかに違法なjavascript構文です...以前はそれほど明白ではありませんでした。

于 2012-11-08T09:43:20.463 に答える
4

最初の表記(括弧なし)では、javascriptの構文があいまいです。ecmascript仕様から:

ExpressionStatementは、 Blockであいまいになる可能性があるため、最初の中括弧で始めることはできません。

ブロックは基本的に内部のすべてのステートメントを評価"a":4,"a":5します。これは、有効でないJSを評価するのと同じで、実際には同じSyntaxErrorを返します。Unexpected token :

そのコードを括弧で囲む(または、グループ化演算子)と、代入式の後にブロックステートメントを続けることができないため、そのあいまいさがなくなります。

var test = {"a":"a","a":"b"}; //test.a === "b"

さらに、このあいまいさは、ブロックステートメントで使用できない演算子または式によって取り除くことができます。条件演算子の一部としてオブジェクトリテラルを返したい場合は、実際のシナリオはほとんど思い浮かびません。

//this *could* come out of a JS minifier:
return x ? (foo(),{"a":"b"}) : (bar(), {"b":"a"});
于 2012-11-08T10:46:44.173 に答える
0

なぜ受け入れられないのですか?単に値を上書きしているだけです。エラーというよりはむしろ機能だと思います。そして、それはさまざまなブラウザで私にとってうまく機能します:http: //jsbin.com/oculon/1/edit それは書くようなものです

var a;

a = 4;
a = 5;

alert(a);
于 2012-11-08T09:35:30.377 に答える
0

エラーではありません。値を別の値で上書きするだけです。

于 2012-11-08T09:43:02.347 に答える
0

FirefoxとChromeのJSパーサーがステートメントと式を処理する方法が異なるため、これはエラーとして評価されると推測しています(確かではありませんが)。つまり、2回目は括弧で囲まれているため、式と見なされます。式で検索する情報が少ないため、誤った値を無視できます。あなたがそうするならば、あなたはそれを見るでしょう...

var a = {'a': 5, 'a': 4};
console.log(a);

それはうまくいきます!また、ここではステートメントの右側にあり、式であることを示唆していることに注意してください。

于 2012-11-08T09:45:00.767 に答える