Gültige Javascript-Objekteigenschaftsnamen

74

Ich versuche herauszufinden, was für den Eigenschaftsnamen eines Javascript-Objekts als gültig angesehen wird. Zum Beispiel

var b = {}
b['-^colour'] = "blue";     // Works fine in Firefox, Chrome, Safari
b['colour'] = "green";      // Ditto
alert(b['-^colour']);       // Ditto
alert(b.colour);            // Ditto
for(prop in b) alert(prop); // Ditto
//alert(b.-^colour);     // Fails (expected)

In diesem Beitrag werden gültige Javascript-Variablennamen aufgeführt, und '- ^ color' ist eindeutig nicht gültig (als Variablenname). Gilt das auch für Objekteigenschaftsnamen? Mit Blick auf das Obige versuche ich herauszufinden, ob

  1. b ['- ^ color'] ist ungültig, funktioniert aber in allen Browsern eigenartig, und ich sollte nicht darauf vertrauen, dass es in Zukunft funktioniert

  2. b ['- ^ color'] ist vollständig gültig, aber es handelt sich nur um eine Form, auf die nur auf diese Weise zugegriffen werden kann - (es wird unterstützt, damit Objekte möglicherweise als Karten verwendet werden können?)

  3. Etwas anderes

Abgesehen davon kann eine globale Variable in Javascript auf der obersten Ebene als deklariert werden

var abc = 0;

könnte aber auch erstellt werden (wie ich es verstehe) mit

window['abc'] = 0;

Das Folgende funktioniert in allen oben genannten Browsern

window['@£$%'] = "bling!";
alert(window['@£$%']);

Ist das gültig? Es scheint den Regeln für die Benennung von Variablen zu widersprechen - oder deklariere ich dort keine Variable? Was ist der Unterschied zwischen einem Variablen- und einem Objekteigenschaftsnamen?

Hawkett
quelle

Antworten:

67

Ja, Objekte können als Karten verwendet werden, und jede Zeichenfolge kann ein Eigenschaftsname sein. Wie Sie festgestellt haben, kann auf einige Eigenschaften nur mit der Klammer-Syntax zugegriffen werden.

window['abc']

greift auf eine Immobilie zu. Es ist keine Variable, obwohl sie sich auf denselben Wert (auf globaler Ebene) bezieht wie:

abc
Matthew Flaschen
quelle
50
"Ein Objekteigenschaftsname kann eine beliebige gültige JavaScript-Zeichenfolge sein oder alles, was in eine Zeichenfolge konvertiert werden kann, einschließlich der leeren Zeichenfolge. Jeder Eigenschaftsname, der keine gültige JavaScript-Kennung ist (z. B. ein Eigenschaftsname mit einem Leerzeichen) oder auf einen Bindestrich oder der mit einer Zahl beginnt) kann nur mit der eckigen Klammer zugegriffen werden. " ( MDN )
Molnarm
12
Márton spricht einen sehr wichtigen Punkt an. Während es auf den ersten Blick so aussieht, als ob jedes JS-Objekt alles als gültigen Objektschlüssel annehmen kann, ist dies nicht ganz der Fall - Márton weist zutreffend darauf hin, dass solche Eigenschaftsschlüssel tatsächlich in Zeichenfolgen konvertiert werden. Bedenken Sievar x=new function X(){};,var y=new function Y(){};undobj={x:true};-obj[y]wird ausgegebentrue, da beidexundy, wenn sie als Objektschlüssel verwendet werden, beide in dieselbe Zeichenfolge konvertiert werden"[object Object]"
ChaseMoskal
4
Um klar zu sein, in Anbetracht des Beispiels meines vorherigen Kommentarsobj[x] === obj[y] === obj["[object Object]"]
ChaseMoskal
Ich möchte darauf hinweisen, dass der Grund für Einschränkungen bei Bezeichnernamen (obwohl JS vermutlich jede Zeichenfolge intern als Variablen- oder Eigenschaftsbezeichner behandeln könnte) in erster Linie darin besteht, syntaktische Mehrdeutigkeiten zu vermeiden. Betrachten Sie einen Eigenschaftsnamen mit einem Bindestrich : x=obj.my-prop. Es wäre unklar (sowohl für den Leser als auch für den Parser), ob dies eine Eigenschaft namens "my-prop" ist oder ob die Absicht bestand, eine Variable "prop" von "obj.my" zu subtrahieren. x=obj["my-prop"]macht deutlich, dass der Name eine Zeichenfolge ist.
Wojtow
15

Benennungsregeln für Objekteigenschaften und Benennungsregeln für Variablen sind getrennt. Der Standard "reserviert" nur eine Handvoll Eigenschaftsnamen (wie prototypeund constructor, IIRC), aber abgesehen von diesen geht jede Zeichenfolge.

Außer wenn die Ausführungsumgebung (dh der Browser) beschließt, natürlich mehr magische Eigenschaften hinzuzufügen. (Ich höre, dass das Einstellen __proto__einige Dinge auf ziemlich seltsame Weise zerstört)

Matti Virkkunen
quelle
Danke Matti - schwer herauszufinden, wer die Antwort geben soll, beide antworteten, aber mit unterschiedlichen (nützlichen) Informationen - ging mit der ersten Antwort. Prost.
Hawkett
1
Wenn Sie __proto__auf null setzen, was bricht das außer der Prototypkette (es ist also eine schnellere Suche nach Eigenschaften), wenn Sie es als einfache Hash-Tabelle für Wertepaare benötigen?
Dimitar Christoff
8
  1. Jedes Mal, wenn Sie eine globale Variable erstellen, erstellen Sie tatsächlich ein neues Mitglied eines globalen Objekts ( windowin der Browserumgebung, globalin Node.js usw.). Aus diesem Grunde window.xist genau die gleiche wie (global) var x, this.xoder einfach nur x.

  2. Das Verständnis von JavaScript- Objekten wie einer Karte ist völlig richtig, da: a) Sie jederzeit dynamisch ein neues Element hinzufügen können; b) Das Element kann einen beliebigen Namen haben - auch Sonderzeichen. c) Sie können versuchen, auf ein nicht vorhandenes Element eines Objekts / einer Karte zuzugreifen, und es ist kein Fehler. d) Sie können ein Element aus einem Objekt entfernen.

  3. Wenn Sie auf Objektelemente mit Standard- Punktnotation (z. B. a.x) zugreifen möchten, dürfen Sie keine anderen Sonderzeichen als _ oder $ verwenden. Auch kann der Name nicht von einer Nummer ausgehen. In allen anderen Fällen müssen Sie eckige Klammern und Anführungszeichen verwenden, um auf Objektelemente zuzugreifen.

ytropek
quelle