5
22 aoû 2008

Introduction


Comme nous l'avons vu dans le tutoriel précédent, JavaScript (JS) n'offre qu'un support partiel (limité?) des concepts liés à la programmation orientée objet (POO). Le concept de classe en tant que telle (pas de mot-clé class dédié) n'existe pas. Toute la POO en JavaScript se base uniquement sur les mécanismes de fonctions,closures et prototype. En même temps que nous apprendrons à créer manuellement nos classes nous utiliserons la bibliothèque Prototype qui offre des mécanismes et raccourcis très intéressants quant à l'utilisation du JavaScript Orienté Objet.

Créer sa propre classe


  • le mot clé this

Le mot clé this fait référence à l'objet en cours. De ce fait il est possible d'avoir accès à tous les attributs et méthodes de l'objet dans le code d'une fonction.

  • L'attribut prototype

Prototype est un attribut particulier que possèdent toutes les classes JS. Il est utilisé lors de l'instanciation de l'objet pour définir un modèle structurel (tiens tiens ne se rapproche t'on pas de la définition d'une classe)? Il permet en effet de définir tous les attributs et méthodes de toutes les instances de la classe.

  • Création d'une classe

Ça y'est, on passe aux choses sérieuses et l'on met les mains dans le cambouis. Mais à peine commencé les choses se gâtent, en effet mauvaise nouvelle, il n'existe pas qu'une manière de créer des classes (pseudo-classes?) en JS.

Pour faire simple, il est tout à fait possible de définir des classes en se basant uniquement sur le concept des fonctions, mais, dans ce cas, le code de chaque méthode serait dupliqué à chaque instanciation d'un nouvel objet alourdissant d'autant la place réservée en mémoire.


function maClasse() {
this.attribut1;
this.attribut2;
this.methodeA = function() {
// code
}
this.methodeB = function() {
// code
}
}

Comment faire alors? Mais oui bien sur, en se basant sur l'objet prototype. En effet, la technique consiste à créer une classe de base. Ensuite celle-ci est enrichie grâce au prototype ce qui permet de ne charger en mémoire qu'une seule partie de l'objet. En se basant sur le schéma précédent cela donnerait :


function maClasse() {
this.attribut1;
this.attribut2;
}

maClasse.prototype.methodeA() = function() {
// code
}

maClasse.prototype.methodeB() = function() {
// code
}

L'inconvénient de cette procédure est que les méthodes ne sont pas définies dans le constructeur lui même. Il est néanmoins possible de contourner cette restriction en se basant sur la propriété "initialized" du constructeur Ce qui donne :


function maClasse() {
this.attribut1;
this.attribut2;
if ( typeOf maClasse.initialized == "undefined" ) {
maClasse.prototype.methodeA() = function() {
// code
}

maClasse.prototype.methodeB() = function() {
// code
}
maClasse.initialized = true;
}
}

Créer sa propre classe avec la bibliothèque Prototype


Merci à Sam Stephenson pour le développement du framework Prototype. En effet vous verrez au travers des quelques lignes qui vont suivre que l'écriture de classe grâce à cette bibliothèque devient plus facile et logique. D'ailleurs de nombreuses autres librairies utilisent à la base Prototype

Allé hop, vérifions si je ne vous ai pas menti. Comment faire pour créer une classe via prototype ? Suivez le guide :


var maClasse = Class.create();

maClasse.prototype = {
initialize : function() {
this.attribut1;
this.attribut2;
}
methodeA : function() {
//code
}
methodeB : function) {
//code
}
}

Dans la bibliothèque prototype initialize joue le rôle de constructeur. Jusqu'ici vous me direz que l'avantage entre la bibliothèque prototype et la manière classique via l'objet prototype (on finit par en perdre son latin) n'est pas flagrant. Mais vous verrez que les avantages sont indéniables lorsque l'on passera aux concepts d'héritage et visibilité.

A propos de l'auteur: 
Arnaud Vandecasteele

Fervent défenseur de l'Open Source, Arnaud s'est spécialisé dans le développement d'application cartographiques web. OpenLayers, PostGIS ou encore Django sont autant d'outils qu'il manipule au quotidien.
S'il n'est pas en face de son ordinateur, vous le retrouverez un GPS à la main en train de cartographier pour OpenStreetMap, de faire voler son drone ou sur un tatami !

Commentaires

pour ma part j'utilise une syntaxe différente selon les besoins :
- objets instanciable, .prototype comme tu l'as montré
- classes statiques (comme en PHP), notation JSON
- pour faire des variables privées, une closure qui entoure ma déclaration de classe

j'ai résumé tout ça ici, en faisant la comparaison avec PHP :
http://jpv.typepad.com/blog/2010/03/javascript-orient%C3%A9-objet-syntax...

Très bon article :)
Lors d'un copier/coller, je n'ai pas fait attention à la petite faute de frappe sur "typeOf" qui doit s'écrire "typeof" (tout en minuscule).

Bonjour,

Tout d'abord merci pour ce code, je ne connaissais pas ces techniques.

Juste pour signaler une petite erreur dans l'utilisation de prototype sans passer par le framework prototype :

maClasse.prototype.methodeA() = function() {
// code
}

Doit etre écrit sans les () :

maClasse.prototype.methodeA = function() {
// code
}

Bonne journée :)

Bonjour,

Merci pour ce post, très instructif!
Mais toutefois, l'utilisation de la bibliothèque prototype me pose un peu problème : j'utilise jQuery dans la plupart de mes scripts alors comment je pourrais appeler prototype et jQuery en même temps dans une même page?
Sinon l'autre méthode avec class.prototype.methode = function (){...} me semble assez intéressant bien qu'elle soit pas très évidente à analyser (à mon avis)

vous pouvez utiliser JQuery et Prototype en même temp, en remplaçant le '$' de JQuery par 'JQuery'