3 votes

Comment appeler directement le setter de la classe mère d'un objet ?

TLDR ; Comment appeler directement le setter de la classe parent d'un objet sans invoquer le setter de l'enfant en dehors de la classe parent et de la classe enfant ?


Je sais que, si la solution existe, elle peut être très difficile à mettre en œuvre ou relever de la magie, mais cela ne me dérange pas. Voici le scénario :

  • Parent est une classe provenant d'une bibliothèque tierce, je ne peux donc pas modifier ce code.
  • Child est une classe de ma base de code, mais j'aimerais garder le code magique en dehors d'elle, car la classe Prop peut être utilisée avec différents " Child Les classes ".
  • Prop est la classe dans laquelle le code magique peut résider si nécessaire.

J'ai besoin d'accéder au Parent L'ensemble de l'équipe de l'UE de l'année dernière a été sélectionné par l'équipe de l'année dernière. x par l'intermédiaire d'un Child sans invoquer le setter de l'objet x de la Child .

Est-ce possible ?

class Parent {
  constructor() {
    this._x = 255;
  }
  set x(v) {
    console.log("Calling Parent setter");
    this._x = v;
  }
  get x() {
    console.log("Calling Parent getter");
    return this._x;
  }
}

class Child extends Parent {
  constructor() {
    super();
    this.prop = new Prop(this);
  }

  set x(v) {
    console.log("AVOID! Calling Child setter");
    super.x = v;
    // Shennanigans I don't want to run
  }

  get x() {
    console.log("Calling Child getter");
    return super.x;
  }
}

class Prop {
  constructor(child) {
    this.child = child;
  }
  setX() {
    const parent = this.child; // Not sure what to do here.
    const old = parent.x;
    parent.x = 0;
    console.log(`parent.x changed from ${old} to ${parent.x}`);
  }
}

const child = new Child();
child.prop.setX();

4voto

Bergi Points 104242

Reflect.set est là pour vous sauver ! Il permet de passer le récepteur séparément :

setX() {
  Reflect.set(Parent.prototype, "x", 0, this.child); // invokes the Parent.protype.x setter
}

Les alternatives seraient Object.getOwnPropertyDescriptor(Parent.prototype, "x").set.call(this.child, 0) ou simplement this.child._x = 0 (si vous n'avez pas besoin d'exécuter le code setter).


Ainsi, bien que cela soit possible, je recommanderais de reconsidérer votre conception. Peut-être que l'héritage n'est pas la bonne approche et que vous devriez utiliser la composition au lieu de l'héritage. extends Parent :

class Child {
  constructor() {
    this.val = new Parent();
  }

  set x(v) {
    … // Shenanigans
    this.val.x = v;
  }

  get x() {
    return this.val.x;
  }

  // (without the Prop helper class for simplicity)
  setX(v) {
    // without shenanigans
    this.val.x = v;
  }
}

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