今天,想总结一下Proxy。在总结之前,请先看一道面试题~
什么样的 a 可以满足 (a === 1 && a === 2 && a === 3) === true 呢?
复制代码
对于这道题,大家肯定的第一想法就是,用到数据劫持/数据代理。
1.用Object.defineProperty方法
let current = 0
Object.defineProperty(window, 'a', {
get () {
current++
return current
}
})
console.log(a === 1 && a === 2 && a === 3) // true
// a === 1 === true
// a === 2 === true
// a === 3 === true
从而 a === 1 && a === 2 && a === 3 === true
复制代码
2.用Proxy方法
let num = 0
let handler = {
get: function(target, name) {
num++
return num
}
}
let p = new Proxy({}, handler)
console.log(p.a === 1 && p.a === 2 && p.a === 3
// p.a === 1 === true
// p.a === 2 === true
// p.a === 3 === true
从而 a === 1 && a === 2 && a === 3 === true
复制代码
两种方法都可以实现,但是不同的是,Proxy返回的是对象。
Proxy: (代理器),可以这样去理解他,在目标对象之前设一层“拦截”,而外界对这个对象的访问,都要通过这层拦截,也因此提供了一种机制,可以对外界的访问进行过滤和改写。
const observedData = new Proxy(data, {
get() {
// 访问源对象属性时调用
},
set() {
// 修改源对象属性时调用
},
deleteProperty() {
// 删除源对象属性时调用
}
});
//第一个参数data: 用Proxy包装的目标对象,可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)
//第二个参数:一个对象,其属性是当执行一个操作时定义代理的行为的函数。
复制代码
所具有的属性描述符:
1.value:(属性值)
2.writeable:(是否为只写)
3.configurable:(是否可配置)
4.enumerable:(是否可枚举)
5.get:(读取数据)
6.set:(操作数据)
复制代码
关于具体用法: 请参考阮大神的 es6.ruanyifeng.com/#docs/proxy