proxy
2019-06-26 本文已影响0人
zooey1184
双向数据绑定3
使用defineProperty能实现数据层的双向绑定,优点是兼容性较高,属于es5的特性,缺点是数据劫持无法监听深层的数据变化,明显的是数据的变化需要额外的逻辑判断并且只能劫持对象属性,如果属性值也是对象,则需要遍历深层,显然能劫持一个完整的对象是我们想要的
所以就有了第二种方式实现双向数据绑定--Proxy(代理)
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
同defineProperty一样,Proxy也是通过set和get是想双向数据绑定
[set] && [get]
get(target, key, reciver)
// target: 目标对象
// key: 目标属性
// reciver: proxy实例本身
var person = {
name: "张三"
};
var proxy = new Proxy(person, {
get: function(target, property) {
if (property in target) {
return target[property];
} else {
throw new ReferenceError("Property \"" + property + "\" does not exist.");
}
}
});
proxy.name // "张三"
proxy.age // 抛出一个错误
set(target, key, value, reciver)
// target: 目标对象
// key: 目标属性
// value: 属性值
// reciver: proxy实例本身
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');
}
}
// 对于满足条件的 age 属性以及其他属性,直接保存
obj[prop] = value;
}
};
let person = new Proxy({}, validator);
person.age = 100;
person.age // 100
person.age = 'young' // 报错
person.age = 300 // 报错
优点
- proxy可以劫持整个对象而非一个属性
- proxy可以直接监听数组的变化
- proxy的支持方法比defineProperty多
缺点
- Proxy的劣势就是兼容性问题,而且无法用polyfill磨平