Visit Mozilla.org

Guide JavaScript 1.5:Création d'objets:Définition d'accesseurs et de mutateurs

Un article de MDC.


[modifier] Définition d'accesseurs et de mutateurs

Un accesseur est une méthode qui permet d'obtenir la valeur d'une propriété particulière. Un mutateur est une méthode qui permet de définir la valeur d'une propriété particulière. De telles méthodes peuvent être définies pour n'importe quel objet prédéfini du langage, ou pour des objets nouvellement créés permettant d'ajouter de nouvelles propriétés. La syntaxe pour définir des accesseurs et des mutateurs est semblable à celle utilisée par les déclarations littérales d'objets.

La session de shell JavaScript suivante illustre comment les accesseurs et les mutateurs fonctionneraient pour un objet o créé par l'utilisateur. Le shell JavaScript est une application permettant aux développeurs de tester du code JavaScript en mode batch ou interactif.

Les propriétés de l'objet o sont les suivantes :

  • o.a - un nombre
  • o.b - un accesseur renvoyant o.a plus 1
  • o.c - un mutateur définissant la valeur de o.a à la moitié de sa valeur précédente
js> o = new Object;
[object Object]
js> o = {a:7, get b() {return this.a+1; }, set c(x) {this.a = x/2}};
[object Object]
js> o.a
7
js> o.b
8
js> o.c = 50
js> o.a
25
js>

La session de shell JavaScript qui suit illustre comment l'on peut étendre le prototype de l'objet Date avec des accesseurs et des mutateurs pour ajouter une propriété year à toutes les instances de la classe prédéfinie Date. Elle utilise les méthodes existantes getFullYear et setFullYear de la classe Date pour définir l'accesseur et le mutateur de la nouvelle propriété year.

js> var d = Date.prototype;
js> d.__defineGetter__("year", function() { return this.getFullYear(); });
js> d.__defineSetter__("year", function(y) { this.setFullYear(y); });

Ces instructions utilisent l'accesseur et le mutateur définis ci-dessus sur un objet Date :

js> var now = new Date;
js> print(now.year);
2000
js> now.year=2001;
987617605170
js> print(now);
Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
Au cours du développement de JavaScript 1.5, des expressions utilisant getter = ou setter = ont été utilisées durant une brève période pour définir de nouveaux accesseurs ou mutateurs sur des objets existants. Cette syntaxe est à présent vivement déconseillée, et déclenchera un avertissement dans les interpréteurs JS 1.5 actuels. Elle provoquera une erreur de syntaxe à l'avenir et doit donc être évitée.

[modifier] Résumé

En principe, les accesseurs et mutateurs peuvent être soit

  • définis à l'aide d'initialisateurs d'objets, soit
  • ajoutés par la suite à un type d'objet existant à l'aide d'une méthode d'ajout d'accesseur ou de mutateur.

Lorsque des accesseurs et mutateurs sont définis à l'aide d'initialisateurs d'objets, tout ce que vous avez à faire est ajouter un préfixe get aux méthodes qui sont des accesseurs et un préfixe set aux méthodes qui sont des mutateurs. Évidemment, la méthode qui est un accesseur ne doit pas recevoir de paramètre, tandis que le mutateur doit prendre exactement un paramètre (la nouvelle valeur à définir). Par exemple :

o = {
  a : 7,
  get b() { return this.a + 1; },
  set c(x) { this.a = x/2; }
};

Des accesseurs et mutateurs peuvent égalemet être ajoutés à un objet à n'importe quel moment après sa création à l'aide de deux méthodes spéciales appelées __defineGetter__ (pour les accesseurs) et __defineSetter__ (pour les mutateurs). Ces deux méthodes reçoivent le nom de l'accesseur ou du mutateur comme premier paramètre, sous la forme d'une chaîne. Le second paramètre est la fonction à appeler comme accesseur ou mutateur. Par exemple, en suivant l'exemple précédent :

o.__defineGetter__("b", function() { return this.a + 1; });
o.__defineSetter__("c", function(x) { this.a = x/2; });

Le choix de l'une de ces deux formes dépendra de votre style de programmation et de la tâche à accomplir. Si vous avez déjà choisi d'utiliser les initialisateurs d'objets pour définir un prototype, vous utiliserez probablement la plupart du temps la première forme. Elle est en effet plus compacte et naturelle. Cependant, si vous avez besoin d'ajouter des accesseurs et des mutateurs par la suite, parce que vous n'avez pas écrit le prototype ou l'objet particulier, alors la seconde forme est la seule possible. Elle représente sans doute mieux la nature dynamique de JavaScript, mais peut rendre le code difficile à lire et à comprendre.