Libellés

dimanche 14 août 2011

Javascript et les objets : héritage, prototype, constructor, ...


Javascript n'est pas un langage orienté objet, mais à l'aide des
prototypes nous pouvons quand même nous en sortir.


### Création d'un objet

Le Js est un langage fonctionnel, ce qui signifie que les fonctions
sont au centre du langage. Et donc, pour créer l’équivalent d'une
classe en js, nous allons commencer par créer son constructeur : une fonction.

   var myClass = function(){
     this.name = 'Romain';
   }


Puis ensuite nous allons instancier cet objet :

   var o = new myClass();
   console.log(o.name);


L'instanciation va se dérouler en plusieurs étapes. Tout d'abord un
objet o tout vide va être créé. Ensuite le constructeur myClass va
être appelé sur cette objet. Le this.name va permettre de créer
l'attribut name dynamiquement.


### Le prototype

Le prototype est le dénominateur commun entre toute les instances d'une même classe.

Si j'ajoute un attribut(ou une méthode) sur le prototype de myClass, alors cet attribut (ou méthode) sera present sur toute les instances de myClass.

   myClass.prototype.age = 25;
  
   console.log(o.age);



### Lien entre le prototype et le constructor.

Comme nous l'avons vu tout à l'heure myClass est une fonction qui va permettre de créer l'objet. C'est le constructeur.

  console.log(typeof myClass) //function


A partir de cette fonction nous pouvons accéder au prototype :

  console.log(myClass.prototype) //{ age: 25 }



Et à partir du prototype nous pouvons retrouver le constructeur. Ce qui signifie qu'à partir de n'importe quel objet, nous pouvons retrouver le constructeur car comme nous l'avons vu précédemment toutes les methodes et attributs d'un prototype sont accessible dans les instances.

   console.log( myClass.prototype.constructor === myClass)
   console.log( o.constructor === myClass)



### L'héritage en javascript

Comme chaque instance hérite de son prototype, il suffit de chainer les prototypes pour faire de l'héritage.

Voici un exemple complet :

    /*
     * On créé le constructeur de l'objet A.
     * Ce constructeur va ajouter automatiquement un attribut name à l'objet.
     */
    var A = function(){
      this.name="Romain";  
    };

    A.prototype.sayHello = function(){
       return "Hello "+this.name;  
    };

    /* On fait de même pour l'objet B */
    var B = function(){
      this.age= 25;  
    };

    /* Maintenant on dit que B hérite de l'objet A */
    B.prototype = new A();

    /* Pour ne pas perdre la référence vers constructeur de B */
    B.prototype.constructor = B;


    /* On vérifie que ça marche */
    var o = new B();
    console.log(o.name);             //Romain
    console.log(o.age);              //25
    console.log(o.sayHello());       //Hello Romain
    console.log(o instanceof B);     // true
    console.log(o instanceof A);     //true
    console.log(o instanceof Object);//true

    /* Et pour le fun, on vérifie que les constructeurs sont logiques */
    console.log(B.prototype.constructor === B);  //true
    console.log(A.prototype.constructor === A);  //true


    /* On peut même recréer un objet à partir d'un autre */
    var p = new o.constructor();
    console.log(p.name);  //Romain
    console.log(p.age);   //25

2 commentaires:

  1. /* On peut même recréer un objet à partir d'un autre */
    var p = new o.constructor();
    console.log(o.name); //Romain
    console.log(o.age); //25


    il aurait fallu ecrire

    console.log(p.name) et console.log(p.age)
    pour voir l'effet interresant de la chose !

    RépondreSupprimer
  2. En effet oui :D, je corrige ça tout de suite

    RépondreSupprimer