Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Développer efficacement en objet

Première approche

1. Rappels

Avant d’aborder concrètement le développement objet en JavaScript, nous allons effectuer quelques rappels sur ce mode de développement. En premier lieu, il faut bien comprendre que ce type de développement a été construit dans le but d’améliorer la qualité du développement en distinguant plusieurs niveaux de conception. Le premier niveau étant d’établir un plan de fabrication et le dernier niveau permettant d’obtenir d’un assemblage objets rendant le service voulu. D’autre part, des méthodes d’analyse et conception ont tenté de suivre ce modèle afin d’assurer une transition de développement plus simple partant de la modélisation du réel vers l’étape de fabrication.

a. Classe

Un objet est généralement construit à partir d’une classe. Cette classe joue le rôle d’usine à objets. Elle possède un plan de fabrication et peut fournir des objets à la demande.

Dans les plans de fabrication, nous avons des propriétés qui stockent des informations propres à chaque objet et des méthodes qui permettent d’interagir avec ces objets.

Une propriété est en réalité une variable dont le contexte d’usage se limite à un objet en particulier. Elle n’existe en quelque sorte qu’à l’intérieur de l’objet, ce qui confère donc à ce dernier un état.

Une méthode d’un objet est aussi une fonction JavaScript mais qui n’existe que dans le contexte de cet objet et ayant un accès aux propriétés de l’objet (donc influant sur l’état de l’objet).

Si nous effectuons une analogie avec les objets de notre entourage, nous pouvons prendre l’exemple d’un téléphone mobile. Ces propriétés sont constituées de son paramétrage et des informations que nous y avons stockées, on constate bien qu’elles sont liées à un appareil uniquement. Les méthodes sont l’ensemble des actions disponibles sur le mobile, comme l’allumer, régler le volume, passer un appel. Si elles sont présentes pour tous les appareils...

Contexte d’exécution

1. this

En JavaScript, this ne désigne pas l’objet issu de l’instance uniquement, mais en réalité il désigne l’objet qui est en train d’être utilisée. Cela signifie que l’interpréteur JavaScript évalue this lors de l’appel d’une méthode, c’est un argument supplémentaire ajouté automatiquement.

Autrement dit, lorsque vous faites référence à this, vous n’êtes jamais certain que cela va concerner votre instance. Cette particularité est assez déroutante pour un développeur objet « classique » mais en réalité offre une grande puissance comme nous allons le voir.

Exemple

function Personne( nom, prenom ) { 
  this.nom = nom; 
  this.prenom = prenom; 
  this.bonjour = function() { 
      alert( "bonjour " + this.prenom ); 
    }; 
} 
 
function Chien( prenom ) { 
  this.prenom = prenom; 
} 
 
var p = new Personne( "brillant", "alexandre" ); 
var c = new Chien( "tobby" ); 
c.bonjour = p.bonjour; 
c.bonjour(); 

Dans l’exemple, nous avons deux classes : Personne et Chien. Ces classes n’ont aucune relation entre elles à la base. Nous associons à la classe Chien la méthode bonjour de la classe Personne, puis nous exécutons cette méthode au travers d’une instance. Nous obtenons bien le message « bonjour tobby ».

this représente l’instance sur laquelle est réalisé un appel de méthode. Cela peut se traduire ainsi :

monInstance.maMethode( ... ) 

En réalité, le comportement interne est celui-ci :

this = monInstance 
maMethode( this, ... ) 

Maintenant, imaginons que nous ayons à passer une référence vers une fonction de notre objet. Pour rappel, JavaScript est un langage qui à la base a été conçu pour fonctionner en relation avec une page HTML. Dans une page HTML, nous avons toutes sortes d’événements qui seront liés aux interactions directes ou indirectes...

Classes prédéfinies

Nous allons maintenant présenter quelques classes d’usage courant. L’objectif n’est pas de présenter de manière exhaustive les propriétés et les méthodes de chaque classe mais de se concentrer sur les plus utiles. Pour obtenir une vue plus complète, vous pouvez vous référer aux liens présents en fin d’ouvrage.

1. Object

Tous les objets créés en JavaScript partagent les propriétés et les méthodes de la classe Object.

La principale propriété est prototype que nous analyserons par la suite et qui a l’avantage de donner accès à des propriétés et à des méthodes présentes de manière unique dans toutes les instances.

Exemple

function Personne( nom, prenom ) { 
  this.nom = nom; 
  this.prenom = prenom; 
} 
 
var p1 = new Personne( "brillant", "alexandre" ); 
var p2 = new Personne( "jean", "dupont" ); 
  
Personne.prototype.bonjour = function() { 
  alert( "bonjour " + this.prenom ); 
}; 
  
p1.bonjour(); 
p2.bonjour();  

Dans cet exemple, nous ajoutons une méthode bonjour à la classe Personne que nous partageons avec toutes les instances. Preuve en est que nous l’avons ajoutée après la création des objets et qu’elle est pourtant disponible avec p1 et p2.

La méthode toString est également présente dans la classe Object pour donner une forme plus lisible de l’objet.

Exemple

function Personne( nom, prenom ) { 
   this.nom = nom; 
   this.prenom = prenom; 
} 
 
var p1 = new Personne( "brillant", "alexandre" ); 
alert( p1 ) ;  

Nous obtenons le résultat [object object] peu agréable signifiant simplement que notre objet est lui-même composé de deux objets (ses propriétés). La méthode alert utilise en réalité la méthode toString, présente par défaut, qui renvoie ce type de résultat. Pour améliorer l’affichage, nous allons étendre un peu notre classe Personne.

function Personne(...

Notions avancées

1. Prototypage

a. Simple

Comme nous l’avons vu sur la classe Object, toutes les classes disposent d’une propriété prototype qui est elle-même un objet. Cette propriété est disponible au sein de chaque instance de la classe. Elle a la particularité d’être exploitée lors d’une invocation de méthodes ou de propriétés. En effet, si une méthode ou une propriété n’est pas trouvée dans l’instance, elle est recherchée dans la propriété prototype.

La propriété prototype va devenir importante dès lors que nous avons plusieurs instances car sinon les définitions de fonction sont dupliquées au sein de chaque instance et donc occupent plus d’espace mémoire.

Exemple

function Personne( nom, prenom ) { 
  this.nom = nom; 
  this.prenom = prenom; 
  this.bonjour = function() { 
    alert( "bonjour " + this.prenom ); 
  }; 
} 
 
var p1 = new Personne( "brillant", "alexandre" ); 
var p2 = new Personne( "brillant", "alexandre" ); 
alert( p1.bonjour == p2.bonjour ); 

Nous avons créé deux instances puis nous comparons la fonction bonjour, elle s’avère différente pour chaque instance. Ceci n’est pas acceptable en termes de ressource et en termes objet car nos méthodes ne devraient pas varier selon les instances. Grâce à la propriété prototype, nous allons pouvoir remédier à cela.

Si nous réécrivons notre exemple, nous avons maintenant :

function Personne( nom, prenom ) { 
  this.nom = nom; 
  this.prenom = prenom; 
} 
Personne.prototype.bonjour = function() {  
  alert( "bonjour " + this.prenom ); 
}; 
 
var p1 = new Personne( "brillant", "alexandre" ); 
var p2 = new Personne( "brillant", "alexandre" ); 
alert( p1.bonjour == p2.bonjour ); 

Nous avons bien maintenant deux méthodes identiques avec notre test d’égalité. Plus nous avons d’objets et plus le gain mémoire...

Framework pour le développement objet

1. Prototype

Prototype (http://www.prototypejs.org) est un framework JavaScript offrant différentes extensions pour l’usage d’Ajax, de DOM, JSON, mais également pour le développement objet, comme nous allons le découvrir.

a. Création d’une classe

Prototype masque toute la mécanique de gestion objet. La classe Class sert à la création de vos classes. On passe en argument le corps de la classe (ce qui correspond à notre objet prototype). La méthode initialize correspond au constructeur.

Exemple

var Personne = Class.create( 
{ 
  initialize : function( nom, prenom ) { 
    this.nom = nom; 
    this.prenom = prenom; 
  }, 
  bonjour : function() { 
    alert( "Bonjour " + this.prenom ); 
  } 
}  
); 

Dans notre exemple, nous avons construit une classe Personne prenant en paramètre du constructeur un nom et un prenom. Il y a peu de modifications par rapport au fonctionnement par défaut. Le concept de prototypage est masqué.

b. Héritage

L’héritage se fait simplement en spécifiant la classe parente dans la méthode create. Si vous avez besoin de surcharger une méthode, il vous suffit de réécrire la signature de la méthode en lui ajoutant un premier paramètre $super. Ce dernier contient une référence vers la méthode parente.

Exemple

var Employe = Class.create(  
  Personne, 
  { 
    initialize : function( $super, nom, prenom, poste ) { 
      $super( nom, prenom ); 
      this.poste = poste; 
    }, 
    bonjour : function( $super ) { 
      $super(); 
      alert( "Vous êtes " + this.poste ); 
    } 
  } 
 ); 
 
var p = new Personne( "brillant", "alexandre" ); 
p.bonjour(); 
 
var e = new Employe( "brillant", "alexandre", "developpeur"...