la poo en javascript modification et consequence

Debut

Dans cette article nous allons voir ce qui se passe quand on modifie les deux éléments qui constituant la poo en JavaScript ces deux éléments sont

-les instances du constructeur (objet).

-le prototype associé aux objets.

Rappel

l'objet :

La poo en JavaScript consiste en une fonction constructeur qui permet de créer des objet par instance chaque objet est indépendant.

le prototype :

Tous les objet possèdent un prototype et tous les objets créé a partir du même constructeur se partage le même prototype.
Un prototype est un peu comme un conteneur de fonction et de méthode.

Pour simplifier la compréhension je n'utiliserais que des attributs (variable) et a aucuns moments des méthodes (fonctions) car pour l'un comme pour l'autre le résultat est le même.

les objet

Un objet est indépendant concrètement si je modifie un objet les autre ne seront pas impacte par cette modification.

Prenons cette exemple pour lequel on créé deux objet

function bonjour(){

this.atribut_1="attribut_de_l'instance"

}

var instance_1=new bonjour()

var instance_2=new bonjour()

On teste les deux instances.

et la on a bien nos deux instances avec attribut_1 qui vaut "attribut_de_l'instance".

On modifie atribut_1 pour la premiere instance instance_1 de cette facon

instance_1.atribut_1="j'ai changé"

Affichons instance_1 et instance_2

instance_2 n'est pas impacté par la modification de instance_1.

Maintenant ajoutons un nouveau attribut a instance_1

instance_1.nouveau_attribut="je suis nouveau"

On teste instance_1 et instance_2

On se rend compte que instance_1 possède un nouveau attribut et que instance_2 a toujours un seul attribut, une fois de plus instance_2 n'est pas impacté par la modification de instance_1.

La modification d'un objet n'impacte donc pas les autres objets

Le prototype

Les méthodes et propriété du prototype appartenant a notre constructeur sont partagé par le constructeur et toutes les instances de ce même constructeur, en conséquence quand on modifie une méthode ou une propriété contenu dans ce prototype toutes les instances attaché a ce prototype sont affecté par la modification.

On reprend le code du début en ajoutant un attribut dans le prototype.

function bonjour(){

this.atribut_1="attribut_de_l'instance"

}

bonjour.prototype.coucou="attribut_du_proto"


var instance_1=new bonjour()

var instance_2=new bonjour()

Maintenant on teste

instance_1.coucou
instance_2.coucou

On obtient pour les deux attribut_du_proto mais rien nous prouve que le prototype est partagé.

Modification a partir du constructeur

pour modifier le prototype a partir du constructeur on précise le constructeur puis on précise que l'on veut modifier le prototype en ajoutant le mot prototype et enfin dans notre cas on modifie l'attribut "coucou" ce qui donne

bonjour.prototype.coucou="j'ai changé"

créons une nouvelle instance.

var instance_3=new bonjour()

on teste

instance_1.coucou
instance_2.coucou
instance_3.coucou

On obtiens pour les trois instances j'ai changé et la on constate que ce soit les anciennes instances et la nouvelle instance elles sont toute affecté par la modification.

La modification c'est faite dynamiquement

De plus on a la preuve que les objets crée a partir du même constructeur se partagent le même prototype.

modification a partir d'un objet

Pour modifier le prototype a partir d'un objet on utilise __proto__ ou Object.getPrototypeOf
la modification ce fera a partir de instance_1 mais on aurait pu le faire a partir des autres.
Ce qui donne

Object.getPrototypeOf(instance_1).coucou="j'ai encore changé

Ou

instance_1. __proto__.coucou="j'ai encore changé

testons

instance_1
instance_2
instance_3

La modification c'est bien opéré et en toute logique elle impacte tous les objets.

certains personnes déconseille l'utilisation de __proto__ cette méthode était a l'origine non standard et pourtant les navigateurs la supportaient et ce n'est que récemment qu' elle a été standardisée avec la spécification ECMAScript 6

Modifier un attribut contenu dans le prototype pour un objet

Modifier un attribut contenu dans le prototype pour un objet sans modifier le prototype qui aurait pour conséquence de modifier cette attribut pour tous les objet est impossible. mais mais mais le système de poo par prototype possède un mécanisme que l'on appel la chaine prototypale

La chaine prototypale est un mécanisme qui fait que quand on appel un attribut ou une méthode la recherche se fait a partir de l'objet et si cette attribut n'est pas trouvé la recherche se fait dans le prototype et en cas d'héritage ou on se retrouve avec plusieurs prototypes la recherche se fera sur le prototype suivant et ainsi de suite j'usqu'a ce que la méthode ou la propriété soit trouvé.

L'avantage c'est que l'on vas pouvoir assigné le nom d'un attribut ou une méthode se trouvant dans le prototype dans un des objets avec un comportement différent l'or de l'appel de cette attribut pour cette objet.

Passons a la pratique

Le code reste inchangé avec un attribut dans le constructeur et un autre dans le prototype et enfin nos deux objets

function bonjour(){

this.atribut_1="premier"

}
bonjour.prototype.coucou="attribut_du_proto"

function init(){

instance_1=new bonjour()
instance_2=new bonjour()
}

onload=init

maintenant on teste le resultat pour instance_1 qui est le meme pour instance_2.


on a donc bien this.atribut_1 dans l'objet et coucou dans le prototype qui vaut attribut_du_proto

maintenant ajoutons l'attribut coucou dans l'objet instance_1 de cette facon.

instance_1.coucou="bip_bip"

on teste instance_1.

et la on se rend bien compte que instance_1 possède l'attribut coucou et que le prototype a toujours l' attribut coucou, et donc quand on fait

instance_1.coucou
instance_2.coucou

pour instance_1 vue que le système de chaine prototypale effectue la recherche de l'attribut d'abord dans l'objet on obtient "bip_bip" et pour instance_2 le système de chaine prototypale n'ayant pas trouvé l'attribut dans l'objet il le recherche dans le prototype et la on obtient "attribut_du_proto" .

en finale on se retrouve bien dans le fait qu'un attribut se trouvant dans le prototype soit différent pour un des objet tout en partageant le même nom.

ce qu'il faut retenir

la modification d'un objet n'impacte pas les autre objets mais que la modification du prototype que ce soit a partir d'un objet ou du constructeur impacte tous les objets. On retiendra aussi que quand on appel un attribut ou une méthode qu'ils soient dans l'objet ou dans le prototype la syntaxe est la même mais quand on veut faire une modification il faut précisé si il s'agit d'un objet ou du prototype. Et enfin on retiendra le principe de la chaine prototypale qui recherche un méthode ou un attribut en commençant par l'objet puis par le prototype du constructeur.

-

Ce document intitulé « la poo en javascript modification et consequence » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous