2017-11-20 3 views
3

Nehmen Sie diese Javascript-Code:Warum wird nach dieser Zuweisung eines Objektliterals kein Semikolon eingefügt?

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

Wenn Sie diesen Code im Browser oder in Knoten laufen, können Sie diese Fehlermeldung erhalten:

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

TypeError: Cannot read property 'forEach' of undefined 

Wenn Sie jedoch ein hinzufügen Semikolon manuell am Ende der ersten Zeile foobar = {};, erhalten Sie nicht mehr diesen Fehler, stattdessen erhalten Sie die erwartete Ausgabe von one und two.

Ich weiß Javascript hat automatische Semikolon Insertion, und ich weiß, dass viele Leute empfehlen Semikolons immer zu verwenden, um solche Probleme zu vermeiden. Meine Frage bezieht sich speziell auf diesen Fall: Warum wurde am Ende der ersten Zeile nicht automatisch ein Semikolon eingefügt? Ein Objektliteral, gefolgt von einem Arrayliteral, ist keine gültige Javascript-Syntax, oder? sehen Lassen Sie mich:

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

Diese tatsächlich druckt undefined, ohne einen Fehler zu werfen! Ich habe nicht damit gerechnet!

Also meine eigentliche Frage ist: Warum ist ein Objekt Literal, gefolgt von einem Array-Literal, in einer Zuordnung, eine syntaktisch korrekte Javascript-Zeile betrachtet, und was macht es?

+3

Eckige Klammern werden sowohl für den Zugriff auf Eigenschaften als auch für Array-Literale verwendet. Ich denke, man könnte sagen, da ist eine inhärente Mehrdeutigkeit, und so behandelt der Dolmetscher das. –

Antwort

7

In Parser Ansicht, wenn Sie nicht das Hinzufügen einer ; betrachtet der Parser es als:

{}["one", "two"] 

Der Index eines leeren Objekts, der nicht verfügbar ist. Technisch ist es also ein Reference Error, da dieser nicht existiert oder undefined. Effektiv wird dies folgendermaßen interpretiert:

undefined.forEach(...) 
3

Der Parser denkt, dass Sie bedeuten:

foobar.two // foobar['two'] = foobar.two 

In Aktion:

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

Betrachten Sie es wie folgt aus:

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