Ich habe viele Fragen zu ES6-Klassen.
Was ist der Vorteil der Verwendung von class
Syntax? Ich habe gelesen, dass public / private / static Teil von ES7 sein wird. Ist das ein Grund?
Ist es außerdem class
eine andere Art von OOP oder ist es immer noch die prototypische Vererbung von JavaScript? Kann ich es mit ändern .prototype
? Oder ist es nur dasselbe Objekt, aber zwei verschiedene Arten, es zu deklarieren?
Gibt es Geschwindigkeitsvorteile? Vielleicht ist es einfacher zu pflegen / zu verstehen, wenn Sie eine große Anwendung wie eine große App haben?
javascript
ecmascript-6
ssbb
quelle
quelle
Antworten:
Die neue
class
Syntax ist, für jetzt , meist syntaktischen Zucker. (Aber Sie wissen, die gute Art von Zucker.) In ES2015-ES2019class
gibt es nichts, was Sie mit Konstruktorfunktionen undReflect.construct
(einschließlich UnterklassenError
undArray
¹) nicht tun können . ( In ES2021 gibt es wahrscheinlich einige Dinge, die Sie damit tun könnenclass
, die Sie sonst nicht tun können: private Felder , private Methoden und statische Felder / private statische Methoden .)Es ist dieselbe prototypische Vererbung, die wir immer hatten, nur mit einer saubereren und bequemeren Syntax, wenn Sie Konstruktorfunktionen (
new Foo
usw.) verwenden möchten. (Besonders im Fall der Ableitung vonArray
oderError
, was Sie in ES5 und früher nicht konnten. Sie können jetzt mitReflect.construct
[ spec , MDN ], aber nicht mit dem alten ES5-Stil.)Ja, Sie können das
prototype
Objekt im Konstruktor der Klasse weiterhin ändern, nachdem Sie die Klasse erstellt haben. ZB ist das völlig legal:Durch die Bereitstellung hierfür eine spezifische Idiom, nehme ich an, es ist möglich , dass der Motor in der Lage sein kann , eine bessere Optimierung des Jobs zu tun. Aber sie können schon schrecklich gut optimieren, ich würde keinen signifikanten Unterschied erwarten.
Kurz gesagt: Wenn Sie Konstruktorfunktionen überhaupt nicht verwenden
Object.create
,class
ist es für Sie nicht hilfreich , sie zu bevorzugen oder ähnlich zu sein.Wenn Sie Konstruktorfunktionen verwenden, gibt es einige Vorteile für
class
:Die Syntax ist einfacher und weniger fehleranfällig.
Es ist viel einfacher (und wiederum weniger fehleranfällig), Vererbungshierarchien mit der neuen Syntax einzurichten als mit der alten.
class
schützt Sie vor dem häufigen Fehler, dassnew
die Konstruktorfunktion nicht verwendet werden kann (indem der Konstruktor eine Ausnahme auslöst, wenn erthis
kein gültiges Objekt für den Konstruktor ist).Das Aufrufen der Version einer Methode des übergeordneten Prototyps ist mit der neuen Syntax viel einfacher als mit der alten (
super.method()
anstelle vonParentConstructor.prototype.method.call(this)
oderObject.getPrototypeOf(Object.getPrototypeOf(this)).method.call(this)
).Hier ist ein Syntaxvergleich für eine Hierarchie:
Beispiel:
Code-Snippet anzeigen
vs.
Live-Beispiel:
Code-Snippet anzeigen
Wie Sie sehen können, gibt es dort viele wiederholte und ausführliche Dinge, die leicht falsch und langweilig sind, um sie erneut einzugeben (weshalb ich damals ein Skript dafür geschrieben habe ).
¹ "In ES2015-ES2018
class
gibt es nichts, was Sie mit Konstruktorfunktionen undReflect.construct
(einschließlich UnterklassenError
undArray
) nicht tun können. "Beispiel:
Code-Snippet anzeigen
quelle
class
. JavaScript ist so flexibel, dass Sie keine Konstruktorfunktionen verwenden müssen, wenn Sie dies nicht möchten. Dies ist das, was Sie tun, aber das unterscheidet sich vonclass
- der springende Punktclass
ist die Vereinfachung der pseudoklassischen Vererbung in JavaScript.Symbol
durcheinander zu kommen ). Aber das Tolle ist wiederum, dass Sie es nicht müssen, wenn Sie sie nicht verwenden möchten. Ich finde in meiner Arbeit, dass Konstruktorfunktionen an vielen Stellen sinnvoll sind und die Semantiknew
die Klarheit verbessert; undObject.create
macht an vielen anderen Orten Sinn, insb. Fassadensituationen. Sie ergänzen sich. :-)class
Syntax wird JavaScript nicht mehr typisiert als zuvor. Wie ich in der Antwort sagte, ist es meistens nur eine (viel) einfachere Syntax für das, was bereits da war. Das war absolut notwendig, die Leute haben ständig die alte Syntax falsch verstanden. Es bedeutet auch nicht, dass Sie die Vererbung mehr als zuvor verwenden müssen. (Und wenn Sie niemals "Klassen" mit der alten Syntax einrichten, müssen Sie dies auch nicht mit der neuen Syntax tun.)ES6-Klassen sind syntaktischer Zucker für das prototypische Klassensystem, das wir heute verwenden. Sie machen Ihren Code prägnanter und selbstdokumentierender, was Grund genug ist, sie zu verwenden (meiner Meinung nach).
Verwenden von Babel zum Transpilieren dieser ES6-Klasse:
wird dir so etwas geben wie:
Die zweite Version ist nicht viel komplizierter, es ist mehr Code zu pflegen. Wenn Sie sich mit Vererbung befassen, werden diese Muster noch komplizierter.
Da die Klassen nach denselben prototypischen Mustern kompiliert werden, die wir verwendet haben, können Sie dieselben Prototypmanipulationen an ihnen durchführen. Dazu gehören das Hinzufügen von Methoden und dergleichen zur Laufzeit, das Zugreifen auf Methoden
Foo.prototype.getBar
usw.ES6 bietet heute einige grundlegende Unterstützung für den Datenschutz, obwohl es darauf basiert, dass die Objekte, auf die Sie nicht zugreifen möchten, nicht exportiert werden. Zum Beispiel können Sie:
und
BAR_NAME
steht anderen Modulen nicht zur direkten Referenzierung zur Verfügung.Viele Bibliotheken haben versucht, dies zu unterstützen oder zu lösen, wie Backbone mit ihrem
extends
Helfer, der einen nicht validierten Hash methodenähnlicher Funktionen und Eigenschaften verwendet, aber es gibt kein einheitliches System zum Aufdecken prototypischer Vererbung, bei dem nicht mit dem Prototyp herumgespielt wird.Da JS-Code immer komplizierter und die Codebasis größer wird, haben wir begonnen, viele Muster zu entwickeln, um Dinge wie Vererbung und Module zu handhaben. Das IIFE, mit dem ein privater Bereich für Module erstellt wird, verfügt über viele Klammern und Parens. Das Fehlen eines dieser Skripte kann zu einem gültigen Skript führen, das etwas völlig anderes ausführt (das Überspringen des Semikolons, nachdem ein Modul das nächste Modul als Parameter übergeben kann, was selten gut ist).
tl; dr: Es ist Zucker für das, was wir bereits tun und macht Ihre Absicht im Code klar.
quelle