Dieser Artikel bietet Ihnen eine Zusammenfassung der Implementierung privater Variablen in ES6 (Codebeispiele). Ich hoffe, dass er für Freunde hilfreich ist.
Als ich „Einführung in ECMAScript 6“ las, sah ich verstreute Implementierungen privater Variablen, daher werde ich es hier zusammenfassen.
class Example { constructor() { this._private = 'private'; } getName() { return this._private } } var ex = new Example(); console.log(ex.getName()); // private console.log(ex._private); // private
Einfache Schreibmethode
Einfaches Debuggen
Gute Kompatibilität
Externer Zugriff und Änderung
Die Sprache verfügt über keinen Koordinationsmechanismus. Beispielsweise listet die for in-Anweisung alle Attribute auf
Namenskonflikt
/** * 实现一 */ class Example { constructor() { var _private = ''; _private = 'private'; this.getName = function() {return _private} } } var ex = new Example(); console.log(ex.getName()); // private console.log(ex._private); // undefined
Kein Namenskonflikt
Extern nicht möglich Zugriff und Änderung
Die Logik des Konstruktors wird kompliziert. Der Konstruktor sollte nun nur die Objektinitialisierung durchführen, um private Variablen zu implementieren, und die Implementierung einiger Methoden ist etwas unklar.
Methoden existieren auf Instanzen, nicht auf Prototypen, und Unterklassen können super nicht zum Aufrufen verwenden
Die Konstruktion verursacht etwas Mehraufwand
/** * 实现二 */ const Example = (function() { var _private = ''; class Example { constructor() { _private = 'private'; } getName() { return _private; } } return Example; })(); var ex = new Example(); console.log(ex.getName()); // private console.log(ex._private); // undefined
Kein Namenskonflikt
Externe können nicht darauf zugreifen und Änderungen vornehmen
Die Schreibmethode ist etwas kompliziert
Die Konstruktion verursacht etwas Mehraufwand
const Example = (function() { var _private = Symbol('private'); class Example { constructor() { this[_private] = 'private'; } getName() { return this[_private]; } } return Example; })(); var ex = new Example(); console.log(ex.getName()); // private console.log(ex.name); // undefined
Kein Namenskonflikt
Kann von außen nicht aufgerufen und geändert werden
Kein Leistungsverlust
Leicht geschrieben Komplex
Kompatibilität ist auch gut
/** * 实现一 */ const _private = new WeakMap(); class Example { constructor() { _private.set(this, 'private'); } getName() { return _private.get(this); } } var ex = new Example(); console.log(ex.getName()); // private console.log(ex.name); // undefined
wenn So geschrieben, haben Sie möglicherweise das Gefühl, dass die Kapselung nicht ausreicht. Sie können auch so schreiben:
/** * 实现二 */ const Example = (function() { var _private = new WeakMap(); // 私有成员存储容器 class Example { constructor() { _private.set(this, 'private'); } getName() { return _private.get(this); } } return Example; })(); var ex = new Example(); console.log(ex.getName()); // private console.log(ex.name); // undefined
Keine Namenskonflikte
Extern Zugriff und Änderung nicht möglich
Die Schreibmethode ist mühsam
Es gibt einige Kompatibilitätsprobleme
Es gibt einen gewissen Leistungsaufwand
class Point { #x; #y; constructor(x, y) { this.#x = x; this.#y = y; } equals(point) { return this.#x === point.#x && this.#y === point.#y; } }
Warum also nicht direkt private Felder nutzen? Zum Beispiel:
class Foo { private value; equals(foo) { return this.value === foo.value; } }
Um es einfach auszudrücken, es ist zu mühsam, und natürlich gibt es Leistungsaspekte ...
Zum Beispiel, wenn wir nicht # verwenden, sondern privat Schlüsselwort :
class Foo { private value = '1'; equals(foo) { return this.value === foo.value; } } var foo1 = new Foo(); var foo2 = new Foo(); console.log(foo1.equals(foo2));
Hier erstellen wir zwei neue Instanzen und übergeben dann foo2 als Parameter an die Instanzmethode von foo1.
Können wir also den Wert von foo2.value ermitteln? Wenn wir direkt foo2.value
werden, können wir den Wert definitiv nicht erhalten. Schließlich handelt es sich um eine private Variable, aber equal ist eine Klassenmethode von Foo. Können wir ihn also erhalten?
Die Antwort ist ja.
Tatsächlich ist dies auch in anderen Sprachen wie Java und C++ der Fall. Mitgliedsfunktionen einer Klasse können auf private Variablen von Instanzen desselben Typs zugreifen Für die Implementierung werden „externe“ Informationen innerhalb der Klasse selbst ausgeblendet. Es ist nicht erforderlich, den Zugriff auf private Variablen zu verbieten. Darüber hinaus kann dies auch der Fall sein Bieten Sie Benutzern Komfort.
Da es möglich ist, den Wert abzurufen, sollte das gedruckte Ergebnis wahr sein, aber was ist, wenn der Wert, den wir übergeben, keine Instanz von Foo, sondern ein anderes Objekt ist?
var foo1 = new Foo(); console.log(foo1.equals({ value: 2 }));
Natürlich kann der Code hier normal ausgeführt werden, aber für den Compiler ist es etwas problematisch, da der Compiler nicht weiß, ob der Wert ein normales Attribut oder ein privates Attribut von foo ist, also muss der Compiler dies tun Um ein Urteil zu fällen, bestimmen Sie zunächst, ob foo eine Instanz von Foo ist, und ermitteln Sie dann den Wert.
Dies bedeutet auch, dass eine solche Beurteilung für jeden Attributzugriff getroffen werden muss. Die Engine wurde rund um den Attributzugriff stark optimiert und ist zu träge zum Ändern, was auch die Geschwindigkeit verringert.
Aber zusätzlich zu dieser Arbeit gibt es noch einige andere Dinge zu beachten, wie zum Beispiel:
Sie müssen den privaten Schlüssel in jede lexikalische Umgebung kodieren
Können diese Eigenschaften durchquert werden?
Wenn private Attribute und normale Attribute denselben Namen haben, wer blockiert dann wen?
So verhindern Sie, dass die Namen privater Attribute erkannt werden.
Weitere Informationen zur Verwendung von # anstelle von privat finden Sie in dieser Ausgabe.
Natürlich können diese Probleme gelöst werden, aber sie sind etwas lästig.
Und wenn Sie # wählen, hat die Implementierungsmethode nichts mit den JavaScript-Objekteigenschaften zu tun. Sie verwendet die Methode private slots
und eine neue Slot-Suchsyntax. Kurz gesagt, sie ist einfacher als die private Implementierungsmethode.
Das obige ist der detaillierte Inhalt vonZusammenfassung der Implementierung privater Variablen in ES6 (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!