Les prototypes

Voir la vidéo
Description Sommaire

Dans ce chapitre nous allons faire le point sur le fonctionnement interne des objets en JavaScript et on va parler de la notion de prototype.

Prototype ?

Si vous inspectez une variable avec votre navigateur vous remarquerez qu'il y a une propriété particulière __proto__. Cette propriété est un objet qui contient aussi des propriétés et des méthodes.

var a = 1
a.__proto__
/*
{
    constructor: function Number()
    toExponential: function toExponential()
    toFixed: function toFixed()
    toLocaleString: function toLocaleString()
    toPrecision: function toPrecision()
    toString: function toString()
    valueOf: function valueOf()
    __proto__: Object
}
*/

Lorsque l'on fait appel à une propriété sur un objet, le JavaScript va chercher si la propriété est présente sur l'objet puis sur son prototype, puis sur le prototype de son prototype (et ainsi de suite...). C'est ce système qui est utilisé en interne pour faire fonctionner les variables de bases.

Par exemple un objet vide (qui n'a aucune propriété) dispose quand même de certaines méthodes. Ces méthodes sont en fait placées dans le prototype de l'objet.

var a = {} // L'objet est vide
a.toString() // Pourtant il a une méthode toString()
console.log(a) // Si on regarde le prototype __proto__ on trouve bien la méthode toString()

On peut utiliser ce système pour créer des nouveaux types de variables par exemple :

// On crée l'objet qui contient les méthodes que l'on souhaite rendre disponibles sur tous nos objets de type "Eleve"
var Eleve = {
    moyenne: function () {
        var somme = 0
        for (var i = 0; i < this.notes.length; i++) {
            somme += this.notes[i]
        }
        return somme / this.notes.length
    }
}

var jean = {notes: [10, 12]} // On crée un eleve en utilisant un objet
jean.__proto__ = Eleve // On change le prototype
jean.moyenne() // 11, La méthode moyenne est disponible sur le prototype et peut donc être appelée

Object.create()

La méthode montrée plus haut n'a rien d'officiel et ne sera jamais utilisée. Lorsque l'on souhaite créer un objet on pourra utiliser la méthode create() sur l'objet Object. Ainsi le code écrit au dessus peut être simplifié :

// On n'écrira jamais ça
var jean = {notes: [10, 12]} // On crée un eleve en utilisant un objet
jean.__proto__ = Eleve // On change le prototype
jean.moyenne() // 11, La méthode moyenne est disponible sur le prototype et peut donc être appelée

// On peut utiliser Object.create()
var jean = Object.create(Eleve) // Crée un objet qui aura comme prototype Eleve
jean.notes = [10, 12]
jean.moyenne() // 11

De la même façon, pour accéder au prototype d'un objet on utilisera la méthode getPrototypeOf().

Object.getPrototypeOf(1) // Number {}

Le constructeur

Object.create() est une méthode relativement récente pour créer des objets. Par défaut on utilise un constructeur.

// La fonction sera utilisée pour "construire" un objet
var Eleve = function (nom) {
    this.nom = nom // On ajoutera une propriété "nom" 
}

var jean = new Eleve('Jean') // On crée une nouvelle "instance" de l'objet Eleve
jean // {nom: 'Jean'}

Ce constructeur a la particularité de donner un prototype particulier aux instances qui sont créées. En effet si on fait

Object.getPrototypeOf(jean) === Eleve.prototype /// true

En résumé, les objets créés à partir d'un constructeur ont comme prototype la propriété prototype de la fonction. Si on souhaite créer une méthode moyenne disponible pour tous les élèves on pourra faire :

// La fonction sera utilisée pour "construire" un objet
var Eleve = function (nom) {
    this.nom = nom // On ajoutera une propriété "nom" 
}

Eleve.prototype.moyenne = function () {
    var somme = 0
    for (var i = 0; i < this.notes.length; i++) {
        somme += this.notes[i]
    }
    return somme / this.notes.length
}

var jean = new Eleve('Jean') 
jean.notes = [10, 12]
jean.moyenne() // 11
Publié
Technologies utilisées
Auteur :
Grafikart
Partager