La syntaxe set permet de lier une propriété d'un objet à une fonction qui sera appelée à chaque tentative de modification de cette propriété.
Syntaxe
{set prop(val) { . . .}}
{set [expression](val) { . . .}}
Paramètres
prop- Le nom de la propriété à lier à la fonction.
val- Un alias pour la variable qui contient la valeur qu'on souhaiterait affecter à
prop. - expression
- Avec ECMAScript 6, il est également possible d'utiliser des expressions pour utiliser un nom de propriété calculé à lier à la fonction.
Description
En JavaScript, un mutateur (ou setter en anglais) peut être utiisé afin d'exécuter une fonction à chaque fois qu'on souhaite modifier la valeur d'une propriété donnée. La plupart du temps, les mutateurs sont utilisés avec les accesseurs (getters) afin de créer une pseudo-propriété. Il n'est pas possible d'avoir à la fois un mutateur et une valeur donnée pour une même propriété.
On notera que set :
- peut avoir un identifiant qui est soit un nombre soit une chaîne de caractères
- doit avoir exactement un paramètre (voir l'article « Incompatible ES5 change: literal getter and setter functions must now have exactly zero or one arguments » (en anglais) pour plus d'informations)
- ne doit pas apparaître dans un littéral objet qui possède un autre
setou une autre propriété avec la même clé :
({ set x(v) { }, set x(v) { } }et{ x: ..., set x(v) { } }seront interdits)
On peut retirer un mutateur d'un objet grâce à l'opérateur delete.
Exemples
Définir un mutateur sur de nouveaux objets avec un littéral objet
Dans l'exemple qui suit, on définit une pseudo-propriété courant pour un objet o qui, lorsqu'elle recevra une valeur, mettra à jour la propriété log avec la valeur reçue :
var o = {
set courant (str) {
this.log[this.log.length] = str;
},
log: []
}
On notera que courant n'est pas défini. Toute tentative pour y accéder renverra undefined.
Supprimer un mutateur grâce à l'opérateur delete
Si on souhaite retirer un mutateur, on peut simplement utiliser l'opérateur delete :
delete o.courant;
Définir un mutateur sur un objet existant avec defineProperty
On peut également ajouter un mutateur sur un objet d'ores et déjà créé. Pour cela, on utilisera la méthode Object.defineProperty().
var o = { a:0 };
Object.defineProperty(o, "b", { set: function (x) { this.a = x / 2; } });
o.b = 10; // On utilise le setter, qui affecte 10 / 2 (5) à 'a'
console.log(o.a) // 5
Utiliser un nom de propriété calculé
Note : Les noms de propriétés calculés font partie d'ECMAScript 6 et sont donc expérimentaux. Il ne sont pas encore largement supportés par les différents navigateurs. S'ils sont utilisés avec des environnements incompatibles, cela entraînera une erreur de syntaxe.
var expr = "toto";
var obj = {
bidule: "truc",
set [expr](v) { this.baz = v; }
};
console.log(obj.bidule); // "truc"
obj.toto = "bidule"; // le mutateur est utilisé
console.log(obj.bidule); // "bidule"
Spécifications
| Spécification | Statut | Commentaires |
|---|---|---|
| ECMAScript 5.1 (ECMA-262) La définition de 'Object Initializer' dans cette spécification. |
Standard | Définition initiale |
| ECMAScript 6 (ECMA-262) La définition de 'Method definitions' dans cette spécification. |
En cours de validation comme recommandation | Ajout des noms de propriétés calculés |
Compatibilité des navigateurs
| Fonctionnalité | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Support simple | 1 | 2.0 (1.8.1) | 9 | 9.5 | 3 |
| Noms de propriétés calculés | Pas de support | 34 (34) | Pas de support | Pas de support | Pas de support |
| Fonctionnalité | Android | Chrome pour Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Support simple | (Oui) | (Oui) | 1.0 (1.8.1) | (Oui) | (Oui) | (Oui) |
| Noms de propriétés calculés | Pas de support | Pas de support | 34.0 (34.0) | Pas de support | Pas de support | Pas de support |
Notes relatives à SpiderMonkey
- À partir de JavaScript 1.8.1, les setters ne sont plus appelés lorsque les propriétés sont définies via les littéraux de tableaux et les littéraux objets.
- À partir de SpiderMonkey 38, utiliser un setter avec des paramètres du reste déclenche une exception
SyntaxErrorafin de respecter la spécification ES6
Voir aussi
getdeleteObject.defineProperty()__defineGetter____defineSetter__- Définir des accesseurs et des mutateurs, dans le Guide JavaScript