87 votes

Comment définir un setter/getter sur un prototype ?

EDIT Oct. 2016 : Veuillez noter que cette question a été posée en 2012. Chaque mois ou presque, quelqu'un ajoute une nouvelle réponse ou un commentaire qui réfute une réponse, mais cela n'a pas vraiment de sens de le faire car la question est probablement dépassée (rappelez-vous, c'était pour Gnome Javascript pour écrire des extensions gnome-shell, pas des trucs de navigateur, ce qui est assez spécifique).

Suivant ma question précédente sur la façon de faire des sous-classes en Javascript, je fais une sous-classe d'une super-classe comme ceci :

function inherits(Child,Parent) {
    var Tmp = function {};
    Tmp.prototype = Parent.prototype;
    Child.prototype = new Tmp();
    Child.prototype.constructor = Child;
}
/* Define subclass */
function Subclass() {
    Superclass.apply(this,arguments);
    /* other initialisation */
}
/* Set up inheritance */
inherits(Subclass,Superclass);
/* Add other methods */
Subclass.prototype.method1 = function ... // and so on.

Ma question est la suivante , comment définir un setter/getter sur le prototype avec cette syntaxe ?

J'avais l'habitude de le faire :

Subclass.prototype = {
    __proto__: Superclass.prototype,
    /* other methods here ... */

    get myProperty() {
        // code.
    }
}

Mais il est évident que ce qui suit ne fonctionnera pas :

Subclass.prototype.get myProperty() { /* code */ }

J'utilise GJS (GNOME Javascript), et le moteur est censé être plus ou moins le même que celui de Mozilla Spidermonkey. Mon code n'est pas destiné à un navigateur, donc tant qu'il est supporté par GJS (je suppose que cela signifie Spidermonkey ?), cela ne me dérange pas s'il n'est pas cross-compatible.

2voto

vsync Points 11280

Voici un exemple simple de Animal → Dog l'héritage, avec Animal ayant un getter et un setter :

//////////////////////////////////////////
// General Animal constructor
function Animal({age, name}) {
  // if-statements prevent triggering the setter on initialization
  if(name) this.name = name
  if(age) this.age = age
}

// an alias "age" must be used, so the setter & getter can use an
// alternative variable, to avoid using "this.age", which will cause
// a stack overflow of "infinite" call stack when setting the value.
Object.defineProperty(Animal.prototype, "age", {
  get(){
    console.log("Get age:", this.name, this._age) // getting
    return this._age
  },
  set(value){
    this._age = value
    console.log("Set age:", this.name, this._age) // setting
  }
})

//////////////////////////////////////////
// Specific Animal (Dog) constructor
function Dog({age = 0, name = 'dog'}) {
  this.name = name
  this.age = age
}

// first, defined inheritance
Dog.prototype = new Animal({});

// add whatever additional methods to the prototype of Dog
Object.assign(Dog.prototype, {
  bark(woff){
    console.log(woff)
  }
})

//////////////////////////////////////////
// Instanciating
var koko = new Animal({age:300, name:'koko'})
var dog1 = new Dog({age:1, name:'blacky'})
var dog2 = new Dog({age:5, name:'shorty'})

console.log(dog1)
koko.age
dog1.age = 3;
dog1.age
dog2.age

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X