Les prototypes Javascript

Cet article a été publié depuis plus de 6 mois, cela signifie que le contenu peut ne plus être d'actualité.

Je travaille depuis quelques semaines sur une application temps réel réalisé avec NodeJS. J'ai longtemps critiqué ce langage qui au fond est plein de qualités, c'est juste qu'en réalité peu de gens le connaissent réellement. C'est donc l'occasion de revoir les basiques de ce langage.

Contrairement à une croyance répandue, Javascript est un langage orienté objet. Certes la syntaxe et la façon d'écrire un objet sont différentes de la plupart des langages, mais cela reste de la programmation objet.

Souvent, lorsque l'on regarde un tutorial sur le Web, un objet est écrit comme cela :

function MyObject() {
    this.myProperty1 = null;
    this.myProperty2 = null;

    this.myMethod1 = function()  {
        return 'method1';
    };

    this.myMethod2 = function(param1, param2) {
        return 'method2';
    };
}

var myInstance = new MyObject();
myInstance.myMethod1(); // => method1

C'est une des méthodes pour déclarer un objet en Javascript, mais ce n'est pas la solution idéale.

Pourquoi ? Parce que en déclarant votre objet ainsi, à chaque création d'une instance de votre objet, la machine virtuelle Javascript va redéfinir l'ensemble des propriétés et méthodes et donc les dupliquer en mémoire.

La bonne solution est donc d'utiliser les prototypes. Un prototype permet d'attacher une propriété à un objet. Il s'agit d'un mécanisme de "fallback". Lorsqu'un appel sur une instance de notre objet est évalué par la machine virtuelle, cette dernière va commencer par vérifier s'il existe une propriété attachée dans le constructeur de l'objet (la définition de la fonction). Si rien n'est trouvé, alors une recherche sera effectuée dans son prototype.

A ce moment-là, si la propriété n'est toujours pas trouvée dans l'objet, une recherche va être effectuée dans l'objet parent (s'il en existe un). Dans le cas contraire, l'évalutation retournera la valeur undefined.

Le gros avantage des prototypes est qu'un prototype est en réalité un pointeur vers une fonction. Cela implique donc que la fonction n'est pas redéfinie et/ou dupliquer par toutes les instances de notre objet.

La bonne façon d'écrire notre code est la suivante :

function MyObject() {
    this.myProperty1 = null;
    this.myProperty2 = null;
}

MyObject.prototype.myMethod1 = function() {
    return 'method1';
}

MyObject.prototype.myMethod2 = function(param1, param2) {
    return 'method2';
}

var myInstance = new MyObject();
myInstance.myMethod1(); // => method1