本篇文章会介绍两种监听对象数据变化的方法。
一、利用 ES5 的 getter 和 setter
侦听一个对象的属性有无变化时,首先,我们可以通过深拷贝的方法作为数据缓存:
举例:
let obj={
name:''
}
let newObj = JSON.parse(JSON.stringify(obj));
set 时,通过 Object.defineProperty, 把传进来的 val 赋给 newObj 的 name 属性,get 时,把 newObj 里面缓存的值取出。
Object.defineProperty(obj,'name',{
get(){
console.log(newObj.name)
return newObj.name;
},
set(val){
if(val===newObj)return;
console.log('new name is',val);
newObj.name=val;
}
})
obj.name='Fat Trump';
上面这种情况的输出结果为:
二、使用 ES6 的 Proxy
使用 Proxy 的方法其实和第一种方法很类似,只是形式看起来不太一样。首先,我们需要写一个处理对象,比方说,假如一个属性不在一个 object 里面,我们不想在拿这个值的时候返回 undefined,那么,我们的处理对象 handler 可以这么写。
let handler = {
get: function(object, propertyName){
console.log(propertyName)
return propertyName in object ? object[propertyName] : 'kitty';
}
};
用 Proxy 让处理对象监听我们的目标对象:
let p = new Proxy({}, handler);
测试一下:
p.a = 'doggy';
console.log(p.a);
console.log(p.b);
输出结果为:
同样的道理,我们可以给处理对象写 setter。
比如下面这个例子,我们想在属性值赋值的时候,检测用户输入的属性值是否合法,我们可以:
let validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
}
obj[prop] = value;
}
};
let person = new Proxy({}, validator);
person.age = 100;
console.log(person.age);
person.age = 'young';
person.age = 300;
输出结果为:
注释掉倒数第二行,我们会看到另外一种异常。
参考:
JavaScript监听对象属性的改变www.jianshu.com