Integrierte Klassen wie Array, Map und andere sind ebenfalls erweiterbar.
Hier erbt PowerArray
beispielsweise vom nativen Array
:
// eine weitere Methode hinzufügen (kann mehr) Klasse PowerArray erweitert Array { isEmpty() { return this.length === 0; } } let arr = new PowerArray(1, 2, 5, 10, 50); alarm(arr.isEmpty()); // FALSCH let filteredArr = arr.filter(item => item >= 10); alarm(filteredArr); // 10, 50 alarm(filteredArr.isEmpty()); // FALSCH
Bitte beachten Sie eine sehr interessante Sache. Integrierte Methoden wie filter
, map
und andere – geben neue Objekte genau des geerbten Typs PowerArray
zurück. Ihre interne Implementierung verwendet dazu die constructor
des Objekts.
Im Beispiel oben:
arr.constructor === PowerArray
Wenn arr.filter()
aufgerufen wird, erstellt es intern das neue Ergebnisarray genau unter Verwendung arr.constructor
und nicht mit dem Basis- Array
. Das ist eigentlich sehr cool, weil wir PowerArray
-Methoden auch im weiteren Verlauf des Ergebnisses verwenden können.
Darüber hinaus können wir dieses Verhalten anpassen.
Wir können der Klasse einen speziellen statischen Getter Symbol.species
hinzufügen. Wenn es existiert, sollte es den Konstruktor zurückgeben, den JavaScript intern verwendet, um neue Entitäten in map
, filter
usw. zu erstellen.
Wenn wir möchten, dass integrierte Methoden wie map
oder filter
reguläre Arrays zurückgeben, können wir Array
in Symbol.species
zurückgeben, wie hier:
Klasse PowerArray erweitert Array { isEmpty() { return this.length === 0; } // Integrierte Methoden verwenden dies als Konstruktor static get [Symbol.species]() { return Array; } } let arr = new PowerArray(1, 2, 5, 10, 50); alarm(arr.isEmpty()); // FALSCH // Filter erstellt neues Array mit arr.constructor[Symbol.species] als Konstruktor let filteredArr = arr.filter(item => item >= 10); // filteredArr ist kein PowerArray, sondern Array alarm(filteredArr.isEmpty()); // Fehler: filteredArr.isEmpty ist keine Funktion
Wie Sie sehen können, gibt .filter
jetzt Array
zurück. Die erweiterte Funktionalität wird also nicht weitergegeben.
Andere Sammlungen funktionieren ähnlich
Andere Sammlungen wie Map
und Set
funktionieren ähnlich. Sie verwenden auch Symbol.species
.
Integrierte Objekte haben ihre eigenen statischen Methoden, zum Beispiel Object.keys
, Array.isArray
usw.
Wie wir bereits wissen, erweitern native Klassen einander. Array
erweitert beispielsweise Object
.
Wenn eine Klasse eine andere erweitert, werden normalerweise sowohl statische als auch nicht statische Methoden geerbt. Dies wurde im Artikel Statische Eigenschaften und Methoden ausführlich erläutert.
Eine Ausnahme bilden jedoch integrierte Klassen. Sie erben keine Statik voneinander.
Beispielsweise erben sowohl Array
als auch Date
von Object
, sodass ihre Instanzen Methoden von Object.prototype
haben. Aber Array.[[Prototype]]
verweist nicht auf Object
, daher gibt es beispielsweise keine statische Methode Array.keys()
(oder Date.keys()
).
Hier ist die Bildstruktur für Date
und Object
:
Wie Sie sehen, gibt es keine Verbindung zwischen Date
und Object
. Sie sind unabhängig, nur Date.prototype
erbt von Object.prototype
.
Das ist ein wichtiger Unterschied der Vererbung zwischen integrierten Objekten im Vergleich zu dem, was wir mit extends
erhalten.