CentraleSupélecDépartement informatique
Gâteau du Glouton
3 rue Joliot-Curie
F-91192 Gif-sur-Yvette cedex
Objets en Javascript

Introduction

Comme vu dans le tuto Javascript, il y a en Javascript une notion d'objet. De façon basique, un objet est une table d'association entre des attributs et des valeurs.

 entre des attributs et des valeurs. Par exemple:
var point = { x : 0 , y : 1 };

définit un objet avec deux attributs x et y, auxquels on accède avec un point (comme en Java)

console.log(point.x);   // 0
console.log(point.y);   // 1

Notez les virgules dans la définition de l'objet.

Méthodes

Comme les fonctions peuvent être manipuler librement, il n'y a fondamentalement pas de différence majeure entre un attribut qui contient une fonction et une méthode. On peut donc rajouter une méthode de translation simplement, en utilisant la référence this pour parler de l'objet courant:

var point = {
  x : 0,
  y : 0,
  translate : function (vx,vy) { this.x += vx; this.y += vy ;} 
};

console.log(point);    // Object { x: 0, y: 0, translate: point.translate() }

point.translate(2,3);
console.log(point);   // Object { x: 2, y: 3, translate: point.translate() }

point.translate(1,1);
console.log(point);   // Object { x: 3, y: 4, translate: point.translate() }

Comme on s'y attend d'après sa définition, la méthode translate modifie l'état de l'objet.

Constructeurs

L'objet point créé plus haut est "tout seul": si on veut créer un deuxième point, il faut tout recommencer. On a donc la notion de constructeur, pour générer une certaine forme d'objet. Par exemple, on pourrait définir une fonction

function Point(x,y) {
  this.x = x;
  this.y = y;
  this.translate = function (vx,vy) { this.x += vx; this.y += vy ;} ;
}

Notez les point-virgules dans la définition de l'objet: cette fois-ci, on définit une fonction usuelle.

Pour créer des objets à partir de cette fonction, on va utiliser le mot-clé new. Chaque invocation va créer un nouvel objet:

var p1 = new Point(0,0);
var p2 = new Point(1,2);

console.log(p1);   // Object { x: 0, y: 0, translate: Point/this.translate() }
p1.translate(2,3);
console.log(p1);   // Object { x: 2, y: 3, translate: Point/this.translate() }
console.log(p2);   // Object { x: 1, y: 2, translate: Point/this.translate() }

On peut "demander" à un objet le constructeur utilisé pour le créer:

console.log(p1.constructor);  // function Point()

Notez qu'il s'agit littéralement de la fonction, dont on peut se resservir si on veur. Mais on peut aussi l'utiliser pour, par exemple, s'assurer du type d'un objet donné ("est-ce un Point ?")

Notion de prototype

Par contre, dans ce shéma p1 et p2 ne partagent aucun attribut (et donc aucune méthode). Cela peut se règler en plaçant la valeur de la méthode translate dans le prototype de Point.

function Point(x,y) {
  this.x = x;
  this.y = y;
}

Point.prototype.translate = function (vx,vy) { this.x += vx; this.y += vy ;} ;

var p1 = new Point(0,0);
var p2 = new Point(1,2);

p1.translate(5,5)

console.log(p1);   // Object { x: 5, y: 5 }
console.log(p2);   // Object { x: 1, y: 2 }

Maintenant, la méthode n'est plus partie prenante de chaque instance de Point, mais fait plutôt partie du "type" Point. En particulier, chaque objet Point est maintenant "compact" en mémoire, ce qui est important dans le contexte d'une application cliente sur un navigateur.

Classe et héritage arbitraire

Cette notion de prototype permets de donner un sens à la notion d'héritage dans le langage dynamiquement typé qu'est javascript: à tout objet est associé un objet prototype. Tout objet hérite de toutes les propriètés (c'est à dire de toutes les méthodes et attributs) de son prototype. Un mécanisme général permet de définir des arborescence arbitraire d'héritage, mais cela sort du cadre de ce cours.

Depuis la version 6 de javascript (ou ECMAscript), on peut par ailleurs utiliser une syntaxe à base de classes, ce qui permet de gèrer plus simplement les questions d'héritage. Pour plus d'information sur ce point, je vous invite à consulter la documentation très bien faite sur le site de Mozilla Dev.