2017-11-20 5 views
3

はこのJavaScriptコードを取る:オブジェクトリテラルの割り当て後にセミコロンが挿入されないのはなぜですか?

foobar = {} 
 
["one", "two"].forEach(item => { 
 
    console.log(item) 
 
})

ブラウザでまたはノードでこのコードを実行した場合、あなたはこのエラーを取得する:

hi.js:2 
["one", "two"].forEach(item => { 
      ^

TypeError: Cannot read property 'forEach' of undefined 

しかし、あなたが追加した場合セミコロンを手動で最初の行の末尾でfoobar = {};とした場合、このエラーは発生せず、代わりにonetwoという予想される出力が得られます。

私はJavascriptに自動セミコロンの挿入があることを知っています。このような問題を避けるため、セミコロンを常に使用することを多くの人が推奨しています。私の質問は、具体的にこのケースについてです:最初の行の最後にセミコロンが自動的に挿入されなかったのはなぜですか?配列リテラルが続くオブジェクトリテラルは、有効なJavascript構文ではありませんか?私は見てみましょう:

foobar = {} ["one", "two"]; 
 
console.log(foobar);

これは実際にはエラーをスローせずにundefinedを印刷します!それを予想しなかった!

本当の質問は、オブジェクトのリテラル、配列リテラル、代入、構文的に正しいJavascript行と見なされる理由は何ですか?

+3

大括弧は、プロパティアクセスと配列リテラルとして使用されます。私はあなたがそこに本質的なあいまいさがあると言うことができると思います、そして、これは通訳がそれをどう扱うかです。 –

答えて

7

、あなたが追加されていません;、パーサはそれを次のように見ます:

{}["one", "two"] 

空のオブジェクトのインデックス。利用できません。したがって、それは存在しないか、またはundefinedというように、技術的には参照エラーです。したがって、これは次のように解釈されます。

undefined.forEach(...) 
3

パーサはあなたが意味すると考えて:

アクションで
foobar.two // foobar['two'] = foobar.two 

:このようなことの

foobar = {one:1,two:2} 
["one", "two"] // returns 2 

思う:パーサビューで

obj = {}; 
obj.foo = 1; 
obj['foo']; // equales 1 
obj;['foo']; // equales obj {foo:1}, ['foo']