Vestavěné třídy jako Array, Map a další jsou také rozšiřitelné.
Například zde PowerArray
dědí z nativního Array
:
// add one more method to it (can do more)
class PowerArray extends Array {
isEmpty() {
return this.length === 0;
}
}
let arr = new PowerArray(1, 2, 5, 10, 50);
alert(arr.isEmpty()); // false
let filteredArr = arr.filter(item => item >= 10);
alert(filteredArr); // 10, 50
alert(filteredArr.isEmpty()); // false
Všimněte si velmi zajímavé věci. Vestavěné metody jako filter
, map
a další – vrátí nové objekty přesně zděděného typu PowerArray
. Jejich interní implementace používá objekt constructor
majetek za to.
Ve výše uvedeném příkladu
arr.constructor === PowerArray
Když arr.filter()
zavolá, interně vytvoří nové pole výsledků pomocí přesně arr.constructor
, nikoli základní Array
. To je vlastně velmi skvělé, protože můžeme nadále používat PowerArray
metody dále na výsledek.
Navíc můžeme toto chování přizpůsobit.
Můžeme přidat speciální statický getr Symbol.species
do třídy. Pokud existuje, měl by vrátit konstruktor, který JavaScript použije interně k vytvoření nových entit v map
, filter
a tak dále.
Pokud bychom chtěli vestavěné metody jako map
nebo filter
abychom vrátili běžná pole, můžeme vrátit Array
v Symbol.species
, jako zde:
class PowerArray extends Array {
isEmpty() {
return this.length === 0;
}
// built-in methods will use this as the constructor
static get [Symbol.species]() {
return Array;
}
}
let arr = new PowerArray(1, 2, 5, 10, 50);
alert(arr.isEmpty()); // false
// filter creates new array using arr.constructor[Symbol.species] as constructor
let filteredArr = arr.filter(item => item >= 10);
// filteredArr is not PowerArray, but Array
alert(filteredArr.isEmpty()); // Error: filteredArr.isEmpty is not a function
Jak můžete vidět, nyní .filter
vrátí Array
. Rozšířená funkcionalita tedy není předávána dále.
Jiné sbírky, například Map
a Set
, pracovat stejně. Používají také Symbol.species
.
Žádné statické dědění ve vestavěných modulech
Vestavěné objekty mají své vlastní statické metody, například Object.keys
, Array.isArray
atd.
Jak již víme, nativní třídy se navzájem rozšiřují. Například Array
rozšiřuje Object
.
Normálně, když jedna třída rozšiřuje druhou, dědí se statické i nestatické metody. To bylo důkladně vysvětleno v článku Statické vlastnosti a metody.
Ale vestavěné třídy jsou výjimkou. Nedědí od sebe statiku.
Například obě Array
a Date
dědit z Object
, takže jejich instance mají metody z Object.prototype
. Ale Array.[[Prototype]]
neodkazuje na Object
, takže zde není například Array.keys()
(nebo Date.keys()
) statická metoda.
Zde je struktura obrázku pro Date
a Object
:
Jak vidíte, mezi Date
není žádné spojení a Object
. Jsou nezávislé, pouze Date.prototype
dědí z Object.prototype
.
To je důležitý rozdíl v dědičnosti mezi vestavěnými objekty ve srovnání s tím, co získáme pomocí extends
.