-
Notifications
You must be signed in to change notification settings - Fork 454
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
实现双向绑定 Proxy 与 Object.defineProperty 相比优劣如何? #25
Comments
PS: Vue2.x 使用 Object.defineProperty 实现数据双向绑定,V3.0 则使用了 Proxy. //拦截器
let obj = {};
let temp = 'Yvette';
Object.defineProperty(obj, 'name', {
get() {
console.log("读取成功");
return temp
},
set(value) {
console.log("设置成功");
temp = value;
}
});
obj.name = 'Chris';
console.log(obj.name); PS: Object.defineProperty 定义出来的属性,默认是不可枚举,不可更改,不可配置【无法delete】 我们可以看到 Proxy 会劫持整个对象,读取对象中的属性或者是修改属性值,那么就会被劫持。但是有点需要注意,复杂数据类型,监控的是引用地址,而不是值,如果引用地址没有改变,那么不会触发set。 let obj = {name: 'Yvette', hobbits: ['travel', 'reading'], info: {
age: 20,
job: 'engineer'
}};
let p = new Proxy(obj, {
get(target, key) { //第三个参数是 proxy, 一般不使用
console.log('读取成功');
return Reflect.get(target, key);
},
set(target, key, value) {
if(key === 'length') return true; //如果是数组长度的变化,返回。
console.log('设置成功');
return Reflect.set([target, key, value]);
}
});
p.name = 20; //设置成功
p.age = 20; //设置成功; 不需要事先定义此属性
p.hobbits.push('photography'); //读取成功;注意不会触发设置成功
p.info.age = 18; //读取成功;不会触发设置成功 最后,我们再看下对于数组的劫持,Object.definedProperty 和 Proxy 的差别 Object.definedProperty 可以将数组的索引作为属性进行劫持,但是仅支持直接对 arry[i] 进行操作,不支持数组的API,非常鸡肋。 let arry = []
Object.defineProperty(arry, '0', {
get() {
console.log("读取成功");
return temp
},
set(value) {
console.log("设置成功");
temp = value;
}
});
arry[0] = 10; //触发设置成功
arry.push(10); //不能被劫持 Proxy 可以监听到数组的变化,支持各种API。注意数组的变化触发get和set可能不止一次,如有需要,自行根据key值决定是否要进行处理。 let hobbits = ['travel', 'reading'];
let p = new Proxy(hobbits, {
get(target, key) {
// if(key === 'length') return true; //如果是数组长度的变化,返回。
console.log('读取成功');
return Reflect.get(target, key);
},
set(target, key, value) {
// if(key === 'length') return true; //如果是数组长度的变化,返回。
console.log('设置成功');
return Reflect.set([target, key, value]);
}
});
p.splice(0,1) //触发get和set,可以被劫持
p.push('photography');//触发get和set
p.slice(1); //触发get;因为 slice 是不会修改原数组的 |
No description provided.
The text was updated successfully, but these errors were encountered: