Comprendre les fonctions constructrices, les instances, le prototype et la chaîne de prototypes en JavaScript

Méthodes de création d'objets en JavaScript

Il existe pluseiurs approches pour instancier des objets dans ce langage.

1. Littéral objet

var vehicule = {
    marque: 'Peugeot',
    modele: '308'
};

2. Utilisation du constructeur intégré Object

var appareil = new Object();
appareil.type = 'Téléphone';
appareil.marque = 'Apple';

3. Fonction constructrice personnalisée

function AnimalEspece(nom, habitat) {
    this.nom = nom;
    this.habitat = habitat;
    this.deplacement = function() {
        console.log('Se déplace');
    }
}

var lion = new AnimalEspece('Lion', 'Savane');
var aigle = new AnimalEspece('Aigle', 'Montagne');
console.log(lion);
lion.deplacement(); // Se déplace
aigle.deplacement(); // Se déplace

Fonctions constructrices détaillées

Une fonction devient constructrice lorsqu'elle est appelée avec le mot-clé new pour initialiser un nouvel objet. Par convention, son nom commence par une majuscule.

function ComposantElectronique(modele, tension) {
    this.modele = modele;
    this.tension = tension;
    this.activer = function() {
        console.log('Composant activé');
    }
}

var composant1 = new ComposantElectronique('LED', '5V');
var composant2 = new ComposantElectronique('Capteur', '3.3V');

Les propriétés définies via this sont des membres d'instance. On peut aussi ajouter des membres statiques directement sur la fonction.

ComposantElectronique.categorie = 'Électronique';
console.log(ComposantElectronique.categorie); // Électronique
console.log(composant1.categorie); // undefined

Le mot-clé new effectue ces étapes : création d'un objet vide, liaison de this, exécution du code constructeur, puis retour de l'objet.

Le prototype des fonctions constructrices

Toute fonction constructrice possède une propriété prototype. Les méthodes définies sur cet objet sont partagées entre toutes les instances, optimisant ainsi l'utilisation mémoire.

function Participant(nom, score) {
    this.nom = nom;
    this.score = score;
}

Participant.prototype.jouer = function() {
    console.log('Participe au jeu');
}

var joueurA = new Participant('Alice', 150);
var joueurB = new Participant('Bob', 200);

console.log(joueurA.jouer === joueurB.jouer); // true

On recommande de placer les propriétés propres à chaque instance dans la constructrice, et les méthodes communes sur le prototype.

L'attribut caché __proto__

Chaque objet possède un lien interne vers le prototype de sa constructrice, accessible via __proto__. Cela permet le mécanisme de recherche de propriétés héritées.

function Ouvrier(nom, metier) {
    this.nom = nom;
    this.metier = metier;
}

Ouvrier.prototype.travailler = function() {
    console.log('Effectue une tâche');
}

var ouvrier1 = new Ouvrier('Claude', 'Maçon');
console.log(ouvrier1.__proto__ === Ouvrier.prototype); // true
ouvrier1.travailler(); // Effectue une tâche

La propriété __proto__ n'est pas standard pour une utilisation directe, mais interne à JavaScript pour orienter la résolution des propriétés.

La propriété constructor

L'objet prototype contient une référence constructor qui pointe vers la fonction constructrice. Lorsqu'on réassigne le prototype, il faut souvent rétablir manuellement cette référence.

function VehiculeMotorise(marque, energie) {
    this.marque = marque;
    this.energie = energie;
}

VehiculeMotorise.prototype = {
    constructor: VehiculeMotorise, // Conservation de la référence
    demarrer: function() {
        console.log('Moteur allumé');
    },
    arreter: function() {
        console.log('Moteur éteint');
    }
}

var voiture = new VehiculeMotorise('Tesla', 'Électrique');
console.log(VehiculeMotorise.prototype.constructor === VehiculeMotorise); // true

Relations fondamentales

La fonction constructrice crée des instances. Chaque instance a un lien __proto__ vers le prototype. Le prototype référence à son tour la constructrice via constructor. Cette relation triangulaire est centrale à la programmation orientée objet en JavaScript.

La chaîne de prototypes

Lors de l'accès à une propriété, JavaScript consulte d'abord l'objet lui-même, puis remonte la chaîne des prototypes jusqu'à Object.prototype, et enfin null si la propriété n'est pas trouvée.

function EtreVivant(type, milieu) {
    this.type = type;
    this.milieu = milieu;
}
EtreVivant.prototype.respirer = function() {
    console.log('Inspire et expire');
}

var plante = new EtreVivant('Végétal', 'Terrestre');
console.log(plante.respirer()); // Inspire et expire
// Chemin de recherche : plante -> EtreVivant.prototype -> Object.prototype -> null

Contexte this dans les prototypes

Dans la fonction constructrice, this fait référence à la nouvelle instance créée. À l'intérieur des méthodes du prototype, this désigne l'instance qui invoque la méthode, permettant un accès aux données propres de l'objet.

Extension des objets natifs

On peut enrichir les prototypes d'objets intégrés comme Array avec des méthodes personnalisées, sans réassigner complètement le prototype pour éviter les effets de bord.

Array.prototype.calculerSommeImpairs = function() {
    var total = 0;
    for (var index = 0; index < this.length; index++) {
        if (this[index] % 2 !== 0) {
            total += this[index];
        }
    }
    return total;
};

var listeNumeros = [1, 2, 3, 4, 5, 6];
console.log(listeNumeros.calculerSommeImpairs()); // 9

Étiquettes: JavaScript Prototypage fonctions constructrices instances Prototypes

Publié le 15 juillet à 06h22