Les classes intégrées comme Array, Map et autres sont également extensibles.
Par exemple, ici PowerArray
hérite du Array
natif :
// ajoute une méthode supplémentaire (peut faire plus) la classe PowerArray étend le tableau { estEmpty() { renvoie this.length === 0; } } let arr = nouveau PowerArray(1, 2, 5, 10, 50); alert(arr.isEmpty()); // FAUX laissez filteredArr = arr.filter(item => item >= 10); alerte(filteredArr); // 10, 50 alert(filteredArr.isEmpty()); // FAUX
Veuillez noter une chose très intéressante. Les méthodes intégrées telles que filter
, map
et autres renvoient de nouveaux objets exactement du type hérité PowerArray
. Leur implémentation interne utilise pour cela la propriété constructor
de l'objet.
Dans l'exemple ci-dessus,
arr.constructor === PowerArray
Lorsque arr.filter()
est appelé, il crée en interne le nouveau tableau de résultats en utilisant exactement arr.constructor
, et non Array
de base. C'est en fait très cool, car nous pouvons continuer à utiliser les méthodes PowerArray
plus loin sur le résultat.
De plus, nous pouvons personnaliser ce comportement.
Nous pouvons ajouter un getter statique spécial Symbol.species
à la classe. S'il existe, il doit renvoyer le constructeur que JavaScript utilisera en interne pour créer de nouvelles entités dans map
, filter
etc.
Si nous souhaitons que des méthodes intégrées telles que map
ou filter
renvoient des tableaux normaux, nous pouvons renvoyer Array
dans Symbol.species
, comme ici :
la classe PowerArray étend le tableau { estEmpty() { renvoie this.length === 0; } // les méthodes intégrées l'utiliseront comme constructeur statique get [Symbol.species]() { retourner le tableau ; } } let arr = nouveau PowerArray(1, 2, 5, 10, 50); alert(arr.isEmpty()); // FAUX // le filtre crée un nouveau tableau en utilisant arr.constructor[Symbol.species] comme constructeur laissez filteredArr = arr.filter(item => item >= 10); // filteredArr n'est pas PowerArray, mais Array alert(filteredArr.isEmpty()); // Erreur : filteredArr.isEmpty n'est pas une fonction
Comme vous pouvez le voir, .filter
renvoie désormais Array
. Les fonctionnalités étendues ne sont donc pas étendues.
D'autres collections fonctionnent de la même manière
D'autres collections, telles que Map
et Set
, fonctionnent de la même manière. Ils utilisent également Symbol.species
.
Les objets intégrés ont leurs propres méthodes statiques, par exemple Object.keys
, Array.isArray
etc.
Comme nous le savons déjà, les classes natives se prolongent les unes les autres. Par exemple, Array
étend Object
.
Normalement, lorsqu’une classe en étend une autre, les méthodes statiques et non statiques sont héritées. Cela a été expliqué en détail dans l'article Propriétés et méthodes statiques.
Mais les classes intégrées constituent une exception. Ils n'héritent pas de la statique les uns des autres.
Par exemple, Array
et Date
héritent de Object
, leurs instances ont donc des méthodes de Object.prototype
. Mais Array.[[Prototype]]
ne fait pas référence Object
, il n'y a donc pas, par exemple, de méthode statique Array.keys()
(ou Date.keys()
).
Voici la structure de l'image pour Date
et Object
:
Comme vous pouvez le voir, il n'y a aucun lien entre Date
et Object
. Ils sont indépendants, seul Date.prototype
hérite de Object.prototype
.
C'est une différence importante d'héritage entre les objets intégrés par rapport à ce que nous obtenons avec extends
.