Javascript 修改对象属性时如何触发回调?
如果我有一门课,比如:Javascript 修改对象属性时如何触发回调?,javascript,class,ecmascript-6,callback,Javascript,Class,Ecmascript 6,Callback,如果我有一门课,比如: class Myclass { constructor(){ this.a = []; this.sum = 0; } update(){ this.sum = this.a.reduce((a, b) => a + b, 0) } } 我实例化这个类: myClass = new Myclass(); 我将一个数字附加到a属性 myClass.a.push(1); myClass.
class Myclass {
constructor(){
this.a = [];
this.sum = 0;
}
update(){
this.sum = this.a.reduce((a, b) => a + b, 0)
}
}
我实例化这个类:
myClass = new Myclass();
我将一个数字附加到a
属性
myClass.a.push(1);
myClass.a.push(2);
如何在每次修改
属性时调用update方法?换句话说,当对象属性被更改时,如何触发回调?可以将对象组织为
class Myclass {
constructor(){
this.a = [];
}
get sum(){
return this.a.reduce((a, b) => a + b, 0)
}
}
如果我没有弄错,调用myClass.sum
将返回数组中a
属性下保存的值的总和。添加将新项推送到a
数组的方法,例如:
class Myclass {
constructor(){
this.a = [];
this.sum = 0;
}
update(){
this.sum = this.a.reduce((a, b) => a + b, 0)
}
pushItem(val) {
this.a.push(val);
this.update();
}
}
myClass = new Myclass();
myClass.pushItem(1);
myClass.pushItem(2);
console.log(myClass.sum);
换句话说,当对象属性被更改时,如何触发回调
这是对上述问题的一般解决办法。如果您只需要a
阵列的特定于用例的解决方案,请忽略此问题
检查是否有比简单的getter/setter更强大的get/set拦截功能。由于您有嵌套的数据结构,因此可能需要递归地使用代理进行包装。大概是这样的:
函数wrapWithProxyCallback(obj,回调){
返回新代理(obj{
获取(目标、键、接收器){
const result=Reflect.get(目标、键、接收器)
//使用代理包装嵌套数据
if(typeof result=='object'&&result!==null){
返回wrapWithProxyCallback(结果,回调)
}
返回结果
},
设置(目标、键、值、接收器){
//对每个集合操作调用回调
回调(目标、键、值/*以及您需要的任何内容*/)
返回Reflect.set(目标、键、值、接收者)
}
})
}
然后像这样使用它:
const wrappedClass=wrapWithCallback(
我的班级,
(target,key)=>console.log(target[key])
)
//这将调用上述回调
包装类a.push(1);
这有点幼稚,但却是一个很好的起点。例如,您可能需要检查嵌套数据是否已由代理包装
您想要做的可能是很好地与透明的反应性保持一致(不过我必须查看回调的内容才能确定这一点)。我认为您应该检查mobx或@nx js/observer util(后者由我编写)以获得生产就绪的盒装解决方案
编辑:我的第一个示例在get操作时触发回调,我将其更正为在set操作时触发。一种方法是扩展Array
并隐藏push
方法
类MyArray扩展了数组{
建造师(参考){
超级();
this.ref=ref
}
推送(值){
超级推送(值)
this.ref.update()
console.log(“被调用”)
}
}
类Myclass{
构造函数(){
this.a=新的MyArray(this);
此值为0.sum=0;
}
更新(){
this.sum=this.a.reduce((a,b)=>a+b,0)
}
}
让myClass=新建myClass()
myClass.a.push(1);
myClass.a.push(2);
console.log(myClass.sum)
一般来说,您可以使用getter/setter来实现此目的,但是.a
属性没有改变,没有分配给它。相反,属性所持有的数组是变异的,而检测它则要复杂一些。