JavaScript类的Getter/Setter

12

有没有一种方法可以监听 JavaScript 类中的属性调用?

例如,当我执行类似以下代码时:

myForm =  new Form();

myForm.name = 'Name'; 

当我设置名称时,我不仅想设置属性,还想更新我的Vuex存储。对于get也是同样的情况,我想从Vuex存储中读取。

我知道有像Proxy这样的东西,但对于这个我需要用一个Proxy对象包装我的类。不太确定我是否喜欢这种方法。

module.exports = new Proxy(new Form({}), {
    get (receiver, name) {
        console.log('getting property from Vuex Store');
    }
});
我需要的是像这样的东西:
module.exports = class Form {

//this should be triggered when form.something
get(property) {
return this[property];
}

//this should be triggered when from.something = 'something'
set(property, value) { 
return this[property] = value;
}
};

这个有最佳实践吗?


1
可能是[JavaScript getters和setters入门指南?](https://dev59.com/o3RA5IYBdhLWcg3w0xfk)的重复问题。 - notgiorgi
1
@notgiorgi,这不是重复的问题。OP询问如何为每个属性设置getter和setter,即使这些属性未定义。 - Stefan Octavian
当您事先知道getter/setter的名称时,请不要使用代理。 - Bergi
@StefanOctavian 从问题中完全无法清楚地看出来这一点。 - Bergi
1个回答

23

Javascript支持获取函数设置函数

class Form{
  set foo(val){
    console.log("setting foo")
    this.fooValue = val;
  }
  
  get foo(){
     console.log("getting foo");
     return this.fooValue;
  }
}

let frm = new Form();
frm.foo = "bar";
console.log(frm.foo);

你可以编写一个 withGetterSetter 方法,通过为对象的每个属性添加一个 getter/setter 来使其更加动态。

var form = {
  a: "aValue",
  b: "bValue"
}

function withGetterSetter(obj){
   var keys = Object.keys(obj);
   var result = {};
   
   for(var i=0;i<keys.length;i++){
       var key = keys[i];
       result[key+"_internal"] = obj[key];
       (function(k){
         Object.defineProperty(result,k, {
          get:function() {
            console.log("getting property:",k);
            return this[k + "_internal"];
          }, 
          set: function(x) { 
            console.log("setting property:",k);
            this[k + "_internal"] = x 
          }
         });
       })(key)
   }
   return result;
}

var setterObj = withGetterSetter(form);
console.log(setterObj.a);
setterObj.a = "updated";
console.log(setterObj.a);

它的工作原理是将每个属性p复制到一个带有p_internal的新对象中,并为原始属性名称创建动态get/set。


我的猜测是OP想要一些通用的getter/setter来一次性获取/设置所有属性。 - dfsq
但是这样的话,我需要为每个属性设置一个setter/getter吗?编辑:@dfsq yap - therabbityouknow
@therabbityouknow 你有多少个属性??每个属性包装起来需要多少额外的工作? - Jamiec
如果我有可能在构造函数中为表单包含的所有字段定义setter和getter,那么这将是很好的。我可以调用new Form(fields)。唯一的问题是它应该是动态的。 - therabbityouknow
defineProperty只能用于对象,对吧?嗯,我会尝试一下的。谢谢。 - therabbityouknow
@therabbityouknow,你不仅可以在对象上使用相同的方法,也可以在类上使用。 - dfsq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接