话不多说,直接上code
const p1 = {
lastName: 'xu',
firstName: 'jie',
get fullName() {
console.log(this)
return this.lastName + this.firstName
},
}
const proxy = new Proxy(p1, {
get(target, key, receiver) {
console.log('get')
return target[key]
},
})
console.log(proxy.fullName)
p1中的fullName是一个get形式的写法,调用是直接p1.fullName,不要加括号。我觉得是被劫持了,
因为打印出p1对象有Object.defineProperty的样子,就是这样 (...)
那么以上的代码输出什么呢(〃'▽'〃)
答案看如下图:
首先说的是为什么只触发一次get呢,明明fullName是一次,fullName里面的lastName是一次,firstName是一次,应该是三次才对啊。
然后this还是p1本身,按理说应该是proxy才对啊。
这都是因为proxy触发get后 return的是 target[key],target是被代理的对象本身,固然达不到我们想要的效果。
receiver解决this问题
const p1 = {
lastName: 'xu',
firstName: 'jie',
get fullName() {
console.log(this)
return this.lastName + this.firstName
},
}
const proxy = new Proxy(p1, {
get(target, key, receiver) {
console.log('get')
return Reflect.get(target, key, receiver)
},
})
console.log(proxy.fullName)
输出结果:
receiver就是proxy实例本身,Reflect.get 的第三个参数可以改变this值,刚好传receiver就是是的fullName里面的this就是proxy实例本身, 然后 this.lastName 和 this.firstName 就都会触发get 。
conclusion
Proxy 和 reflect 应该结合一起用。Vue3源码里面就是这两个东西在做 reactive (响应式)