简体   繁体   English

ES5 / 6类中多个相同的getter / setter函数的好的解决方案?

[英]Good solution for multiple identical getter/setter functions in ES5/6 classes?

I'm looking for an elegant way to declare identical getter/setters for multiple properties in ES6 classes. 我正在寻找一种优雅的方法来为ES6类中的多个属性声明相同的getter / setter。

Rather than having a slew of: 而不是一:而就:

  set prop_1(value){
      this.prop_1 = value;
      console.log(`set prop_1 = ${value} and calling updateroom`);
      db.updateRoom(this, 'prop_1');
  }

... ...

  set prop_n(value){
      this.prop_n = value;
      console.log(`set prop1 = ${value} and calling updateroom`);
      db.updateRoom(this, 'prop_n');
  }

I'd like to do something a little more maintainable like this in the class definition adjacent to the other getters and setters: 我想在类定义中与其他getter和setter相邻的地方做一些更可维护的操作:

['prop_1', 'prop_2' ... 'prop_n'].forEach(prop => {
      set [prop](value) {
        this[prop] = value;
        console.log(`set ${prop} = ${value} and calling updateroom`);
        db.updateRoom(this, prop);
      }
});

But of course can't do that inside the class definition as literals aren't one of the things syntactically allowed there. 但是当然不能在类定义中做到这一点,因为文字不是语法上允许的事情之一。

Can't even add the setters to the class definition after declaration later via eg: 声明之后甚至无法通过以下方法将setter添加到类定义中:

class Room {
// stuff
}

['initialised', 'type', 'owner'].forEach(prop => {
    Object.defineProperty(Room, prop, {
      set: function(value) {
        this[prop] = value;
        console.log(`set ${prop} = ${value} and calling updateroom`)
        db.updateRoom(this, prop);
      }
})

as there is no instance at that point. 因为当时没有实例。

So end up going down an arcane path of decorating the constructor, which just means anyone trying to figure out what the heck I was trying to achieve afterwards ends up with a half hour headache and way more complexity. 因此,最终走上了装饰构造函数的神秘道路,这意味着任何想弄清楚我后来想要实现的目标的人最终都会头疼半小时,而且会更加复杂。

Am I missing something, has anyone figured out an elegant way of coding this efficiently without repetition of the getter-setters? 我是否错过了某些东西,是否有人想出了一种优雅的方法来有效地对此进行编码,而无需重复使用吸气剂?

I'd like to do something a little more maintainable like this in the class definition adjacent to the other getters and setters: 我想在类定义中与其他getter和setter相邻的地方做一些更可维护的操作:

 ['prop_1', 'prop_2' ... 'prop_n'].forEach(prop => { set [prop](value) { this[prop] = value; console.log(`set ${prop} = ${value} and calling updateroom`); db.updateRoom(this, prop); } }); 

and

Can't even add the setters to the class definition after declaration later via eg:...as there is no instance at that point. 以后甚至不能通过例如:...声明将setter添加到类定义中,因为此时没有实例。

Right, but you can use Object.defineProperty to do it, setting the properties on the object that will be the prototype of those instances ( Room.prototype ). 是的,但是您可以使用Object.defineProperty进行操作,在将成为这些实例原型的对象上设置属性( Room.prototype )。 After the class declaration: class声明后:

class Room {
    // ...
}

...you can add those setters to Room.prototype : ...您可以将这些设置器添加到Room.prototype

['prop_1', 'prop_2'/* ... 'prop_n'*/].forEach(prop => {
    Object.defineProperty(Room.prototype, prop, {
        set: function(value) {
            // ...save the value somewhere (*NOT* `this[prop] = value;`,
            // which will call the setter again, resulting in a stack
            // overflow error...
        }
    });
});

Remember that class notation is mostly syntactic sugar on prototypical inheritance (but, you know, the good kind of sugar). 请记住, class符号在原型继承中主要是语法糖(但您知道,糖是一种很好的糖)。 You still have a Room.prototype object, and it's perfectly valid to add things to it outside the class declaration. 您仍然有一个Room.prototype对象,并且在class声明之外向其中添加内容是完全有效的。

Live Example (in this example, I just store the values on a separate values property object) : 实时示例(在此示例中,我只将值存储在单独的values属性对象上)

 class Room { constructor() { this.values = {}; } } ['prop_1', 'prop_2', 'prop_n'].forEach(prop => { Object.defineProperty(Room.prototype, prop, { set: function(value) { console.log(`set ${prop} = ${value}...`); this.values[prop] = value; }, get: function() { return this.values[prop]; } }); }); const r = new Room(); r.prop_1 = 42; console.log("r.prop_1 = ", r.prop_1); r.prop_2 = "Answer"; console.log("r.prop_2 = ", r.prop_2); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM