Propriétés en JavaScript : les méthodes watch et __defineGetter__ pour Firefox
J'ai récemment découvert par hasard les méthodes watch et unwatch spécifique à Firefox. Ces méthodes permettent de s'abonner à la modification de la valeur d'un attribut d'un objet.
Exemple :
var o = {p:1}
o.watch("p",
function (id,oldval,newval) {
Sys.Debug.trace("o." + id + " changed from " + oldval + " to " + newval)
return newval
});
o.p = 2
o.p = 3
delete o.p
o.p = 4
o.unwatch('p')
o.p = 5
Affiche :
o.p changed from 1 to 2
o.p changed from 2 to 3
o.p changed from undefined to 4
Attention les méthodes watch et unwatch sont spécifique (propriétaire) à Firefox !!! Ce code ne fonctionne pas sous IE, Opera ou Safari. D'après ce que j'ai compris, il s'agit de vieux restes de Netscape.
Ce comportement peux nous être très utile lorsque l'on veut, par exemple, valider les données. En JavaScript il n'y a pas de vérification de type, grâce à ce système on pourrait s'assurer qu'on assigne bien le bon type à telle ou telle propriété et que sa valeur est correcte; l'autre intérêt est le déclenchement d'événements, ou alors l'utilisation de debugger. Malheureusement il n'existe pas de comportement similaire pour IE et cela me semble impossible de reproduire ce comportement.
Dans le même ordre d'idée, Firefox dispose des méthodes __defineGetter__ et __defineSetter__ qui permettent de définir des getter et setter comme pour les propriétés .net :
var o = {_p:3};
o.__defineGetter__('p', function(){
return this._p;
});
o.__defineSetter__('p', function(value){
this._p = value;
});
Sys.Debug.trace(o.p); // => 3
o.p = 5;
Sys.Debug.trace(o.p); // => 5
Sys.Debug.trace(o._p); // => 5
On peut également définir les getter et setter inline :
o = {
_p:7,
get p() { return this._p; },
set p(value) { this._p = value; }
};
Ces méthodes fonctionnent sous Safari et Firefox. Malheureusement je n'ai pas trouvé de documentation précises sur ces méthodes, d'après ce que j'ai lu avec les exemples proposés sur le site de mozilla, elles sont définies au niveau de JavaScript 1.5 c'est à dire un des implémentations de la spécification EcmaScript Revision 3, mais je n'ai rien trouvé de tel dans les specs ... Les pages sur defineGetter et defineSetter sur le wiki mozilla ne sont pas rédigées, heureusement les exemples d'utilisation sont assez explicites pour ne pas avoir la nécessité de spécifications ...