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

Javascript ES5/6类中多个相同的getter/setter函数的好解决方案?,javascript,class,getter-setter,Javascript,Class,Getter Setter,我正在寻找一种优雅的方法来为ES6类中的多个属性声明相同的getter/setter 而不是有一大堆: set prop_1(value){ this.prop_1 = value; console.log(`set prop_1 = ${value} and calling updateroom`); db.updateRoom(this, 'prop_1'); } 我想在与其他getter和setter相邻的类定义中做一些更易于维护的事情: [

我正在寻找一种优雅的方法来为ES6类中的多个属性声明相同的getter/setter

而不是有一大堆:

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

我想在与其他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);
      }
});
['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);
      }
});
但是当然不能在类定义中这样做,因为从语法上讲,文本是不允许的

甚至不能在稍后通过以下方式声明后将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);
      }
})
因为在这一点上没有实例

因此,最终会走上一条装饰构造函数的神秘之路,这意味着任何试图弄明白我之后到底想实现什么的人最终都会头疼半个小时,而且会变得更加复杂

我是否遗漏了什么,有没有人想出了一种优雅的方法来高效地编写代码,而不必重复getter setter

我想在与其他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);
      }
});
['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);
      }
});

甚至不能在稍后通过声明后将setter添加到类定义中,例如:…因为此时没有实例

是的,但是您可以使用设置这些实例的原型对象的属性(
Room.prototype
)。在
声明之后:

class 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...
        }
    });
});
记住,
class
notation在原型继承上主要是语法上的糖分(但是,你知道,最好的糖分)。您仍然有一个
Room.prototype
对象,在
声明之外添加东西是完全有效的

实时示例(在本例中,我只是将值存储在单独的
values
property对象上):

教室{
构造函数(){
this.values={};
}
}
['prop_1'、'prop_2'、'prop_n'].forEach(prop=>{
对象定义属性(房间、原型、道具、{
设置:函数(值){
log(`set${prop}=${value}…`);
此.values[prop]=值;
},
get:function(){
返回这个.values[prop];
}
});
});
常数r=新房间();
r、 项目1=42;
console.log(“r.prop_1=”,r.prop_1);
r、 prop_2=“答案”;

console.log(“r.prop_2=”,r.prop_2)
主体中声明,它们也会去那里。太好了,谢谢。我仍然在摸索JS类语法,而它只是原型继承上的语法糖,而不是新事物,这一事实是关键。“我知道它必须比我做的要简单。”罗布·皮克林:很高兴这有帮助。你可能也会觉得有用;除此之外,它还展示了
class
语法如何与ES5及更早版本中没有
class
语法的情况下执行大致相同的操作相关。