Detaillierte Erklärung von Objektliteralen in JS

Detaillierte Erklärung von Objektliteralen in JS

Vorwort

Vor ES6 waren Objektliterale (auch als Objektinitialisierer bekannt) in JavaScript sehr einfach. Es können zwei Arten von Eigenschaften definiert werden:

  • Schlüssel-Wert-Paar {name1: value1}
  • Berechnete Eigenschaftswerte mit Gettern { get name(){..} } und Settern { set name(val){..}}
var meinObjekt = {
  myString: 'Wert 1',
  hol meineNummer() {
    gib dies zurück._meineNummer;
  },
  setze meineNummer(Wert) {
    this._myNumber = Zahl(Wert);
  },
};
meinObjekt.meinString; // => 'Wert 1'
meinObjekt.meineNummer = '15';
meinObjekt.meineNummer; // => 15

js ist eine prototypbasierte Sprache, daher ist alles ein Objekt. Für die Objekterstellung, Konfiguration und den Zugriff auf Prototypen muss eine konstruktionserleichternde Sprache bereitgestellt werden.

Das Definieren eines Objekts und das Festlegen seines Prototyps ist eine gängige Aufgabe. Am besten ist es, den Prototyp direkt in einer einzigen Anweisung auf dem Objektliteral festzulegen.

Leider erlauben die Einschränkungen von Literalen keine einfache Lösung, um dies zu erreichen. Sie müssen object.create() in Verbindung mit einem Objektliteral verwenden, um den Prototyp festzulegen.

var meinProto = {
  EigenschaftExists: Funktion(Name) {
    Gib darin den Namen zurück;
  }
};

var meineNumbers = Object.create(myProto);
meineZahlen['arrat'] = [1, 6, 7];
myNumbers.propertyExists('array'); // => wahr
myNumbers.propertyExists('Sammlung'); // => false

Meiner Meinung nach ist diese Lösung nicht flexibel genug. JS basiert auf Prototypen. Warum ist es so mühsam, Objekte mit Prototypen zu erstellen?

Glücklicherweise verbessert sich auch JS langsam. Viele frustrierende Probleme in JS werden schrittweise gelöst.

Dieser Artikel zeigt, wie ES6 die oben genannten Probleme löst und Objektliterale mit zusätzlichen Funktionen verbessert.

  • Festlegen des Prototyps für die Objektkonstruktion
  • Methodendeklaration
  • Super Anruf
  • Berechnete Eigenschaftsnamen

1. Setzen Sie den Prototyp auf Objektkonstruktion

Wie Sie wissen, besteht eine Möglichkeit, auf den Prototyp eines vorhandenen Objekts zuzugreifen, darin, die Getter-Eigenschaft __proto__ zu verwenden:

var meinObjekt = {
  Name: "Hallo Welt!",
};
meinObjekt.__proto__; // => {}
meinObjekt.__proto__.isPrototypeOf(meinObjekt); // => wahr

myObject.__proto__ gibt das Prototypobjekt von myObject zurück.

Beachten Sie, dass die Verwendung von object.__proto__ als Getter/Setter nicht empfohlen wird. Bei alternativen Ansätzen sollten Sie die Verwendung von Object.getPrototypeOf() und Object.setPrototypeOf() in Betracht ziehen.

ES6 ermöglicht die Verwendung von __proto__ als Eigenschaftsnamen und das Festlegen des Prototyps in {__proto__: protoObject}.

Als nächstes verwenden wir die Eigenschaft __proto__, um das Objekt zu initialisieren und den obigen Code zu optimieren:

var meinProto = {
  EigenschaftExists: Funktion(Name) {
    Gib darin den Namen zurück;
  },
};
var meineZahlen = {
  __proto__: meinProto,
  Array: [1, 6, 7],
};
myNumbers.propertyExists('array'); // => wahr
myNumbers.propertyExists('Sammlung'); // => false

Das myNumbers-Objekt wird mit dem speziellen Eigenschaftsnamen proto und dem Prototyp myProto erstellt. Dieses Mal erstellen wir es mit einer einzigen Anweisung, ohne dass eine zusätzliche Funktion wie object.create() oben erforderlich ist.

Wie Sie sehen, ist die Codierung mit __proto__ einfach und ich mag immer einfache und klare Lösungen.

Reden wir über etwas, das nicht zum Thema gehört. Ich finde es merkwürdig, dass eine einfache und flexible Lösung so viel Arbeit und Design erfordert. Wenn die Lösung einfach wäre, könnte man meinen, dass die Entwicklung auch leicht wäre. Aber auch das Gegenteil ist der Fall:

  • Es ist kompliziert, es einfach und klar zu machen
  • Es ist leicht, es kompliziert und schwer verständlich zu machen.

Wenn etwas zu komplex oder schwierig zu verwenden erscheint, muss es möglicherweise noch weiter verfeinert werden.

1.1 Sonderfälle der __proto__-Verwendung

Auch wenn __proto__ einfach aussieht, gibt es einige Sonderfälle, die Sie kennen sollten.

Sie können __proto__ nur einmal in einem Objektliteral verwenden, andernfalls meldet JS einen Fehler:

var Objekt = {
  __proto__: {
    toString: Funktion() {
      return '[Objektnummern]'
    }
  },
  Zahlen: [1, 5, 89],
  __proto__: {
    toString: Funktion() {
      gibt '[Objekt ArrayOfNumbers]' zurück
    }
  }
};

Das obige Beispiel verwendet die Eigenschaft __proto__ zweimal im Objektliteral, was nicht zulässig ist. In diesem Fall wird ein Fehler ausgegeben: SyntaxError: Doppelte __proto__-Felder sind in Objektliteralen nicht zulässig.

JS schränkt ein, dass als Wert der __proto__-Eigenschaft nur ein Objekt oder Null verwendet werden kann. Die Verwendung primitiver Typen (Zeichenfolgen, Zahlen, Boolesche Werte) oder nicht definierter Werte wird ignoriert und ändert den Prototyp des Objekts nicht.

var objUndefined = {
  __proto__: undefiniert,
};
Objekt.getPrototypeOf(objUndefined); // => {}
var Objektnummer = {
  __proto__: 15,
};
Objekt.getPrototypeOf(objNumber); // => {}

Das Objektliteral verwendet undefined und die Zahl 15, um den __proto__-Wert festzulegen. Da als Prototypen nur Objekte oder Null zulässig sind, wird der __proto__-Wert ignoriert, aber objUndefined und objNumber haben immer noch ihren Standardprototyp: ein einfaches JS-Objekt {}, .

Natürlich wäre es auch seltsam, zu versuchen, einen primitiven Typ zu verwenden, um den Prototyp eines Objekts festzulegen.

Seien Sie auch vorsichtig, wenn Objektliterale eine Zeichenfolge haben, die als '__proto__' { ['__proto__']: protoObj } ausgewertet wird. Auf diese Weise erstellte Eigenschaften ändern den Prototyp des Objekts nicht, sondern erstellen lediglich eine eigene Eigenschaft mit dem Schlüssel '__proto__'.

2. Kurzform der Methodendefinition

Sie können eine kürzere Syntax zum Deklarieren von Methoden in Objektliteralen verwenden, indem Sie das Funktionsschlüsselwort und den Doppelpunkt : weglassen. Dies wird als Kurzform der Methodendefinition bezeichnet.

Als nächstes verwenden wir die Kurzformmethode, um einige Methoden zu definieren:

var Sammlung = {
  Artikel: [],
  hinzufügen(Element) {
    dies.items.push(item);
  },
  erhalte(Index) {
    gib dies zurück.items[index];
  },
};
Sammlung.Hinzufügen(15);
Sammlung.Hinzufügen(3);
Sammlung.get(0); // => 15

Ein schöner Vorteil ist, dass auf diese Weise deklarierte Methoden als Funktionen benannt werden, was für Debugging-Zwecke nützlich ist. Die Ausführung von collection.add.name aus dem obigen Beispiel würde den Funktionsnamen „add“ zurückgeben.

3. Verwendung von Super

Eine interessante Verbesserung in JS ist die Möglichkeit, das Schlüsselwort „super“ zu verwenden, um auf geerbte Eigenschaften aus der Prototypkette zuzugreifen. Schauen Sie sich das folgende Beispiel an:

var berechnen = {
  Zahlen: null,
  SummeElemente() {
    returniere dies.numbers.reduce(function(a, b) {
      gib a + b zurück;
    });
  },
};
var Zahlen = {
  __proto__: berechnen,
  Zahlen: [4, 6, 7],
  SummeElemente() {
    wenn (diese.Zahlen == null || diese.Zahlen.Länge === 0) {
      gebe 0 zurück;
    }
    return super.sumElements();
  },
};
Zahlen.SummeElemente(); // => 17

calc ist der Prototyp des Numbers-Objekts. In der sumElements-Methode von Zahlen können Sie mit dem Schlüsselwort super auf die Methode aus dem Prototyp zugreifen: super.sumElements()

Letztendlich ist super eine Abkürzung für den Zugriff auf geerbte Eigenschaften aus der Prototypenkette eines Objekts.

Im vorherigen Beispiel können Sie versuchen, den Prototyp aufzurufen, indem Sie calc.sumElements() direkt ausführen, was zu einem Fehler führt. Allerdings kann super.sumElements() korrekt aufgerufen werden, da es auf die Prototypenkette des Objekts zugreift. Und stellen Sie sicher, dass die Methode sumElements() im Prototyp mithilfe von this.numbers korrekt auf das Array zugreift.

Durch das Vorhandensein von „super“ wird deutlich, dass die geerbten Eigenschaften verwendet werden.

3.1 Einschränkungen bei der Verwendung von Super

super kann nur innerhalb einer Kurzmethodendefinition in einem Objektliteral verwendet werden.

Wenn Sie versuchen, über eine normale Methodendeklaration { name: function(){} } darauf zuzugreifen, gibt JS einen Fehler aus:

var berechnen = {
  Zahlen: null,
  SummeElemente() {
    returniere dies.numbers.reduce(function(a, b) {
      gib a + b zurück;
    });
  },
};
var Zahlen = {
  __proto__: berechnen,
  Zahlen: [4, 6, 7],
  SummeElemente: Funktion() {
    wenn (diese.Zahlen == null || diese.Zahlen.Länge === 0) {
      gebe 0 zurück;
    }
    return super.sumElements();
  },
};
// Wirft SyntaxError: 'super'-Schlüsselwort hier unerwartet
Zahlen.SummeElemente();

Die Methode sumElements wird als Eigenschaft definiert: sumElements: function() {…}. Da „super“ nur innerhalb einer Kurzmethode verwendet werden kann, führt ein Aufruf in diesem Kontext zu einem SyntaxError: „super“ keyword unexpected here .

Diese Einschränkung hat keine großen Auswirkungen auf die Deklaration von Objektliteralen. Aufgrund der kürzeren Syntax ist es normalerweise besser, die Kurzform der Methodendefinition zu verwenden.

4. Berechnete Eigenschaftsnamen

Vor ES6 wurden Objekte mit Literalwerten initialisiert, normalerweise statischen Zeichenfolgen. Um eine Eigenschaft mit einem berechneten Namen zu erstellen, müssen Sie einen Eigenschaftenzugriffsmechanismus verwenden.

Funktion Präfix(prefStr, Name) {
  gibt prefStr + '_' + Name zurück;
}
var Objekt = {};
Objekt[Präfix('Zahl', 'Pi')] = 3,14;
Objekt [Präfix ('bool', 'false')] = falsch;
Objekt; // => { Zahl_Pi: 3,14, bool_false: false }

Natürlich ist diese Art der Definition von Eigenschaften erfreulich.

Verwenden Sie als Nächstes die Kurzformmethode, um das obige Beispiel zu ändern:

Funktion Präfix(prefStr, Name) {
  gibt prefStr + '_' + Name zurück;
}
var Objekt = {
  [Präfix('Zahl', 'Pi')]: 3,14,
  [Präfix('bool', 'false')]: falsch,
};
Objekt; // => { Zahl_Pi: 3,14, bool_false: false }

[prefix('number', 'pi')] legt den Attributnamen fest, indem der Ausdruck prefix('number', 'pi') ausgewertet wird (d. h. 'number_pi').

Entsprechend setzt [prefix('bool', 'false')] den zweiten Attributnamen auf 'bool_false'.

4.1 Symbol als Attributname

Symbole können auch als berechnete Eigenschaftsnamen verwendet werden. Stellen Sie einfach sicher, dass Sie sie in eckige Klammern einschließen: {[Symbol('name')]:'Prop value'}

Verwenden Sie beispielsweise die spezielle Eigenschaft Symbol.iterator und iterieren Sie über die Eigenschaftsnamen des Objekts selbst. Wie im folgenden Beispiel gezeigt:

var Objekt = {
   Nummer 1: 14,
   Nummer 2: 15,
   string1: 'hallo',
   string2: 'Welt',
   [Symbol.Iterator]: Funktion *() {
     var eigenes = Object.getOwnPropertyNames(dieses),
       Stütze;
     während(Eigenschaft = eigenes.pop()) {
       Ertragsstütze;
     }
   }
}
[...Objekt]; // => ['Zahl1', 'Zahl2', 'Zeichenfolge1', 'Zeichenfolge2']

[Symbol.iterator]: function *() { } Definiert eine Eigenschaft, die verwendet wird, um über die Eigenschaften eines Objekts zu iterieren. Das Spread-Operator-Objekt nimmt einen Iterator und gibt eine Liste seiner eigenen Eigenschaften zurück.

5. Ruhe und erweiterte Eigenschaften

Mit verbleibenden Eigenschaften können Sie Eigenschaften eines Objekts sammeln, die nach der Zuweisung und Zerstörung verbleiben.

Das folgende Beispiel sammelt die verbleibenden Eigenschaften nach der Destrukturierung eines Objekts:

var Objekt = {
  propA: 1,
  propB: 2,
  EigenschaftC: 3,
};
let { propA, ...restObject } = Objekt;
EigenschaftA; // => 1
restObject; // => { propB: 2, propC: 3 }

Spread-Eigenschaften ermöglichen das Kopieren eigener Eigenschaften eines Quellobjekts in ein Objektliteral. In diesem Beispiel sammelt das Objektliteral zusätzliche Eigenschaften aus dem Quellobjekt in das Objekt:

var Quelle = {
  propB: 2,
  EigenschaftC: 3,
};
var Objekt = {
  propA: 1,
  ...Quelle,
};
Objekt; // => { propA: 1, propB: 2, propC: 3 }

6. Zusammenfassung

Sogar die relativ kleine Konstruktion eines Objektliterals wurde in ES6 erheblich verbessert.

Der Prototyp eines Objekts kann direkt von einem Initialisierer mit dem Eigenschaftsnamen __proto__ festgelegt werden. Dies ist einfacher als die Verwendung von Object.create().

Bitte beachten Sie, dass __proto__ Teil des Anhangs B des ES6-Standards ist und von seiner Verwendung abgeraten wird. Diese Add-On-Implementierung ist für Browser erforderlich, für andere Umgebungen jedoch optional. Diese Funktion wird in NodeJS 4, 5 und 6 unterstützt.

Das Formular zur Methodendeklaration ist jetzt kürzer, sodass Sie das Funktionsschlüsselwort nicht eingeben müssen. Bei der vereinfachten Methode können Sie das Schlüsselwort „super“ verwenden, das einen einfachen Zugriff auf geerbte Eigenschaften in der Prototypenkette des Objekts bietet.

Wenn der Eigenschaftsname zur Laufzeit berechnet wird, können Sie jetzt den berechneten Eigenschaftsnamen [Ausdruck] verwenden, um ein Objekt zu initialisieren.

Oben finden Sie eine ausführliche Erläuterung von Objektliteralen in JS. Weitere Informationen zu JS-Objektliteralen finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Detaillierte Erklärung der Prinzipien und der Verwendung von JavaScript-Objektliteralen und -Konstruktoren
  • Eine kurze Diskussion über JS-Literale, Objektliteralzugriff und die Verwendung des Schlüsselworts in
  • Grundlegendes zu Javascript-Objektliteralen
  • Erläuterung von JavaScript-Objektliteralen
  • Eine vollständige Liste der Zeichenfolgenoperationen, die häufig in JavaScript-Interviews getestet werden (einschließlich ES6)
  • Detaillierte Erläuterung des Implementierungsprinzips der JavaScript ES6-Klasse
  • Lösen Sie das Problem, dass das Ausführen von JS-Dateien im Knotenterminal die ES6-Syntax nicht unterstützt
  • JS objektorientierte Programmierung - detaillierte Erklärung der Klassenvererbung in ES6
  • Analyse der Klassenverwendung in nativem JavaScript es6

<<:  So mounten Sie eine neue Festplatte auf einem Linux-Cloud-Server

>>:  MySQL-Datumsfunktionen und Datumskonvertierungs- und -formatierungsfunktionen

Artikel empfehlen

Eine kurze Analyse der Grundkonzepte von HTML-Webseiten

Was ist eine Webseite? Die Seite, die nach dem HT...

Schritte zum Importieren von Millionen von Daten in MySQL mit .Net Core

Inhaltsverzeichnis Vorbereitende Vorbereitung Imp...

Das Konzept und die Eigenschaften von benutzerdefinierten MySQL-Variablen

Ein MySQL Custom Value ist ein temporärer Contain...

Detaillierte Installation und Verwendung von SSH in der Ubuntu-Umgebung

SSH steht für Secure Shell, ein sicheres Übertrag...

Implementierung eines einfachen Chatroom-Dialogs basierend auf WebSocket

In diesem Artikel finden Sie den spezifischen Cod...

So fügen Sie CentOS7 systemd benutzerdefinierte Systemdienste hinzu

systemd: Das Service-Systemctl-Skript von CentOS ...

Centos7-Installation des FFmpeg-Audio-/Video-Tools – einfaches Dokument

ffmpeg ist ein sehr leistungsfähiges Tool zur Aud...

Detaillierte Erklärung zur Verwendung von JavaScript-Funktionen

Inhaltsverzeichnis 1. Deklarieren Sie eine Funkti...

Vue implementiert Tab-Tab-Umschaltung

In diesem Artikelbeispiel wird der spezifische Co...

Gründe, warum MySQL 8.0-Statistiken ungenau sind

Vorwort Unabhängig davon, ob es sich um Oracle od...