Wenn Sie dies tun 0[0], verwandelt der JS-Interpreter den ersten 0in ein NumberObjekt und versucht dann, auf die [0]Eigenschaft dieses Objekts zuzugreifen undefined.
Es liegt kein Syntaxfehler vor, da die Eigenschaftszugriffssyntax 0[0]in diesem Zusammenhang von der Sprachgrammatik zugelassen wird. Diese Struktur (unter Verwendung von Begriffen in der Javascript-Grammatik) ist NumericLiteral[NumericLiteral].
Der relevante Teil der Sprachgrammatik aus Abschnitt A.3 der ES5 ECMAScript-Spezifikation ist folgender:
Literal ::
NullLiteral
BooleanLiteral
NumericLiteral
StringLiteral
RegularExpressionLiteral
PrimaryExpression :
this
Identifier
Literal
ArrayLiteral
ObjectLiteral
( Expression )
MemberExpression :
PrimaryExpression
FunctionExpression
MemberExpression [ Expression ]
MemberExpression . IdentifierName
new MemberExpression Arguments
So kann man dem Grammatiker durch diesen Fortschritt folgen:
MemberExpression [ Expression ]
PrimaryExpression [ Expression ]
Literal [ Expression ]
NumericLiteral [ Expression ]
Und ähnlich Expressionkann es auch sein, wenn NumericLiteralwir der Grammatik folgen, sehen wir, dass dies erlaubt ist:
NumericLiteral [ NumericLiteral ]
0[0]Dies bedeutet, dass dies ein zulässiger Teil der Grammatik und somit kein SyntaxError ist.
Zur Laufzeit dürfen Sie dann eine Eigenschaft lesen, die nicht vorhanden ist (sie wird nur als gelesen undefined), solange die Quelle, aus der Sie lesen, entweder ein Objekt ist oder eine implizite Konvertierung in ein Objekt aufweist. Und ein numerisches Literal hat tatsächlich eine implizite Konvertierung in ein Objekt (ein Zahlenobjekt).
Dies ist eine der oft unbekannten Funktionen von Javascript. Die Typen Number, Booleanund Stringin Javascript sind in der Regel intern als Primitive (nicht ausgewachsene Objekte) gespeichert. Hierbei handelt es sich um eine kompakte, unveränderliche Speicherdarstellung (wahrscheinlich auf diese Weise aus Gründen der Implementierungseffizienz). Javascript möchte jedoch, dass Sie diese Grundelemente wie Objekte mit Eigenschaften und Methoden behandeln können. Wenn Sie also versuchen, auf eine Eigenschaft oder Methode zuzugreifen, die vom Grundelement nicht direkt unterstützt wird, zwingt Javascript das Grundelement vorübergehend in einen geeigneten Objekttyp, wobei der Wert auf den Wert des Grundelements festgelegt wird.
Wenn Sie eine objektähnliche Syntax für ein Grundelement wie verwenden 0[0], erkennt der Interpreter dies als Eigenschaftszugriff für ein Grundelement. Die Antwort darauf besteht darin, das erste 0numerische Grundelement zu einem vollständigen NumberObjekt zu zwingen, auf das es dann auf die [0]Eigenschaft zugreifen kann . In diesem speziellen Fall ist die [0]Eigenschaft eines Number-Objekts undefinedder Grund, weshalb Sie diesen Wert erhalten 0[0].
Hier ist ein Artikel über die automatische Konvertierung eines Grundelements in ein Objekt zum Zwecke des Umgangs mit Eigenschaften:
Das geheime Leben von Javascript-Primitiven
Hier sind die relevanten Teile der ECMAScript 5.1-Spezifikation:
9.10 CheckObjectCoercible
Löst TypeError aus, wenn value undefinedoder ist null, andernfalls wird zurückgegeben true.

11.2.1 Property Accessors
- BaseReference sei das Ergebnis der Auswertung von MemberExpression.
- Sei baseValue GetValue (baseReference).
- Es sei propertyNameReference das Ergebnis der Auswertung von Expression.
- Es sei propertyNameValue GetValue (propertyNameReference).
- Rufen Sie CheckObjectCoercible (baseValue) auf.
- Es sei propertyNameString ToString (propertyNameValue).
- Wenn die syntaktische Produktion, die ausgewertet wird, im Code für den strengen Modus enthalten ist, sei strict wahr, andernfalls sei strict falsch.
- Gibt einen Wert vom Typ Referenz zurück, dessen Basiswert baseValue ist und dessen referenzierter Name propertyNameString ist und dessen strikter Modus-Flag streng ist.
Ein operativer Teil für diese Frage ist Schritt 5 oben.
8.7.1 GetValue (V)
Hier wird beschrieben, wie beim Aufrufen des Werts als Eigenschaftsreferenz ToObject(base)die Objektversion eines beliebigen Grundelements abgerufen wird .
9.9 ToObject
Diese beschreibt , wie Boolean, Numberund StringPrimitiven sind an eine Objektform mit der umgewandelt [[PrimitiveValue]] internem Eigenschaftssatz entsprechend.
Als interessanter Test, wenn der Code so war:
var x = null;
var a = x[0];
Es wäre immer noch keine Syntax zur Analysezeit werfen , da dies technisch rechtliche Syntax ist, aber es wäre eine Typeerror zur Laufzeit werfen , wenn Sie den Code ausführen , weil , wenn die oben Eigenschaftenaccessoren Logik auf den Wert angewandt wird x, wird es nennen CheckObjectCoercible(x)oder rufen Sie ToObject(x)die wird sowohl eine Typeerror aus , wenn xist nulloder undefined.
true[0]oder""[0]