proxy和reflect中的receiver

39 阅读1分钟

话不多说,直接上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的样子,就是这样 (...)

那么以上的代码输出什么呢(〃'▽'〃)
答案看如下图:

proxy1.jpg

首先说的是为什么只触发一次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)

输出结果:

proxy2.jpg

receiver就是proxy实例本身,Reflect.get 的第三个参数可以改变this值,刚好传receiver就是是的fullName里面的this就是proxy实例本身, 然后 this.lastName 和 this.firstName 就都会触发get 。

conclusion

Proxy 和 reflect 应该结合一起用。Vue3源码里面就是这两个东西在做 reactive (响应式)