Prototypes et héritage en JavaScript

Prototypes et héritage en JavaScript
L'héritage est un concept de la programmation orientée objet, même si JavaScript prend en charge entièrement l'héritage entre les parents et les enfants, le travail est loin de la programmation traditionnelle orientée objet, c'est-à-dire que tout dans JavaScript est cartographié sur le constructeur primitif Objet (Objet avec une capitale O) c'est pourquoi il est également connu comme l'objet maître. Ne pas interpréter mal cet objet maître avec l'objet DataType.

JavaScript est souvent mal interprété comme un OLangue orientée vers le BJECT mais en réalité, ce n'est pas vrai; JavaScript est une langue basée sur un prototype. L'héritage en javascript est réalisé par quelque chose appelé Héritage prototypique. Pour comprendre cela, nous devons d'abord familiariser avec le fonctionnement d'un constructeur en JavaScript, comment un objet est créé contre un constructeur, et ce qu'est le prototype.

C'est l'un des sujets avancés de JavaScript et nous allons vous prendre très lentement et essayer d'expliquer chaque petit peu d'informations avec des extraits, commençons.

Comment fonctionne un constructeur en javascript

Conventionnellement, constructeurs sont des fonctions spéciales qui sont exécutées chaque fois qu'un objet est créé contre une classe; en javascript, Chaque expression de fonction est un constructeur. Maintenant, si vous venez d'un langage de programmation trivial et que vous avez un arrière-plan avec une programmation orientée objet, alors vous allez être confus. Par conséquent, essayez de ne pas comparer les concepts JavaScript avec une programmation orientée objet trivial.

Même si avec l'arrivée de la version ES 6 de JavaScript, le mot-clé "Classe"A été ajouté à JavaScript, mais cela n'est pas utilisé pour mettre en œuvre le concept d'hérédité. Dans JavaScript, vous pouvez créer des objets mappés sur la fonction, Oui - les fonctions.

Imaginez une fonction créée avec le code suivant:

var personne = fonction ()

Comme mentionné ci-dessus, que chaque expression de fonction est un constructeur, cela peut être prouvé en utilisant les lignes suivantes à l'intérieur de la fonction:

var personne = fonction (nom)
ce.name = name;
ce.Âge = 20

Maintenant, comme vous pouvez le voir, nous créons une fonction et à l'intérieur du corps de la fonction, nous définissons et initialisons les propriétés de l'objet, tout comme nous le faisons dans tout constructeur conventionnel normal. Maintenant, créons des objets mappés à cela Personne Fonction du constructeur avec les lignes de code suivantes:

var p1 = nouvelle personne ("John");
var p2 = nouvelle personne ("Albert");

Maintenant, nous créons des objets, mais nous n'avons pas de méthode à l'intérieur d'objets qui nous renverront le nom de la personne que nous venons de créer, alors créons cette fonction à l'intérieur du constructeur du Personne objet.

var personne = fonction (nom)
ce.name = name;
ce.âge = 20;
ce.getName = function ()
retour (ceci.nom)

Maintenant, nous devons appeler cette fonction à partir de chaque objet individuel en utilisant les lignes de code suivantes:

console.journal (P1.getName ());
console.journal (P2.getName ());

Après avoir exécuté tout cet extrait, nous obtenons la sortie suivante sur la console:

Maintenant, voici le problème majeur avec l'utilisation de ce type de modèle, imaginez que vous avez 100 objets de Personne, ces 100 objets auront leur posséder 100 différents nom() les fonctions:

C'est parce que ces objets sont les instances du Personne, le rendant ainsi redondant sur la mémoire. C'est là que le Propriété prototype entre en jeu.

La propriété prototype

Chaque fonction et chaque objet ont une propriété nommée Prototype, Ce prototype contient des méthodes et des propriétés d'une fonction, et cette propriété prototype est partagée entre toutes les instances / objets qui sont mappés à la fonction, jetez un œil à cet extrait:

Si nous devions créer des objets basés sur cette fonction "X», Ils hériteraient des méthodes et des propriétés à l'intérieur du«prototype«De la fonction. Dans notre exemple, la fonction principale serait le Personne Et les objets sont P1, P2, comme:

Utilisation de la propriété prototype pour créer un héritage prototypal

Notre principal problème avec l'approche triviale était que chaque objet avait le sien nom() fonctions, plus les objets sont plus nom() Fonctions dans la mémoire. Pour supprimer ceci, nous écrivons le fonction getName () En dehors de l'expression du constructeur et à l'intérieur de la propriété Prototype à l'aide de la syntaxe:

ObjectName.prototype.Methodname

Notre code se transforme en:

var personne = fonction (nom)
ce.name = name;
ce.âge = 20;

personne.prototype.getName = function ()
retourner ceci.nom;

var p1 = nouvelle personne ("John");
var p2 = nouvelle personne ("Albert");
console.journal (P1.getName ());
console.journal (P2.getName ());

La sortie est exactement la même que la dernière fois:

Mais la différence cette fois est que plutôt que chaque objet ayant le sien nom() Fonction, chaque objet accède au nom() Fonction dans son parent et en utilisant cette fonction pour exécuter l'instruction qui lui est donnée. C'est appelé "Héritage prototypique»En JavaScript. Finalement, ne le rendant pas redondant dans la mémoire.

Objet maître

Tout en javascript est essentiellement un objet, cela signifie que tout en javascript est basé sur Objet (avec une capitale o).

Pour expliquer cela, utilisez les lignes de code suivantes et ouvrez la console du navigateur.

Var Demo = fonction ()

console.dir (démo);

Vous créez une fonction avec un constructeur vide et le console.diron() affiche les détails de démo () Définition de fonction sur la console, vous verrez ceci:

Étendre la petite pointe de flèche et examiner le __proto__ propriété de cette fonction, le __proto__ La propriété nous dit sur quel objet a-t-il été cartographié cette fonction, vous verrez ceci:

Maintenant, créons une instance de cette fonction de démonstration et examinons son __proto__ comme:

Var Demo = fonction ()

Soit x = nouvelle démo ();
console.dir (x);

Après avoir exécuté ce code, vous devriez voir la sortie suivante sur la console:

Développez ceci et examinez le constructeur sur lequel l'instance «x» a été cartographiée, vous verrez:

Signifiant cet objet X a la démo parent, et nous savons déjà que le Demo de fonctionest mappé sur l'objet javascript. Cela crée une chaîne de prototypage comme:

L'object "X«Peut accéder aux méthodes et propriétés de l'objet maître, créant ainsi une chaîne d'héritage.

Si nous regardons dans notre console pour la dernière fois, nous pouvons examiner que l'objet maître a cette seule méthode dans sa propriété prototype qui est toString () comme:

Et nous appelons cette propriété sur l'objet "X»Et sur la fonction démo que vous avez créé comme:

console.journal (x.toString ());
console.journal (démo.toString ());

Vous obtenez la sortie comme:

Vous pouvez voir, l'objet et la fonction ont pu accéder à cette méthode même s'il n'a pas été défini à l'intérieur.

C'est ainsi que l'héritage fonctionne en javascript via des prototypes.

Conclusion

L'héritage en JavaScript est très différent de notre définition conventionnelle de l'héritage dans la programmation orientée objet. En JavaScript, nous réalisons l'héritage à l'aide d'une propriété appelée prototype. Vous avez appris comment un constructeur fonctionne en javascript, quel est le prototype propriété, comment tout dans JavaScript est un objet en apprenant Objet maître. De plus, vous avez appris l'héritage prototypique et le chaînage prototype, et vous avez pu accéder aux méthodes et propriétés de la Objet maître en utilisant le objet que tu as créé.