在es6 Proxy中,推荐使用Reflect.get而不是target[key]的原因

目前中文检索得不到这个问题的答案,大多数的博客都是直接使用了Reflect.get而没有给出原因。为了解释这个问题,首先还要说明另一个问题。

Reflect.get(target, prop, receiver) 以及 Proxy中的 handler.get(target, prop, receiver) 这当中的receiver是什么?

直接摘抄MDN的说明

Reflect.get(target, prop, receiver)中的参数receiver:如果target对象中指定了getter,receiver则为getter调用时的this值。

handler.get(target, prop, receiver)中的参数receiver:Proxy或者继承Proxy的对象。

参数receiver存在的意义

单独来看,我很难想出receiver参数的使用场景,甚至会认为这个参数没有存在的意义,但既然这么设计就一定有它存在的意义。先看下面的例子:



 

let People = new Proxy({
    _name: 'zky',
    get name() {
        return this._name
    }
}, {
    get: function (target, prop, receiver) {
        return target[prop]
    }
})
let Man = { _name: 'zky_man' }
Man.__proto__ = People // Man继承People
console.log(Man._name) // zky_man
console.log(Man.name) // zky

问题来了,Man中已经存在_name属性,但这里Man.name返回的却是原型链上的_name属性,
原因很好解释:get name中的this默认绑定为People

那怎么解决这个问题呢?这里就该receiver上场了,修改上面的例子:


 


let People = new Proxy({
    _name: 'zky',
    get name() {
        return this._name
    }
}, {
    get: function (target, prop, receiver) {
        return Reflect.get(target, prop, receiver)
    }
})
let Man = { _name: 'zky_man' }
Man.__proto__ = People // Man继承People
console.log(Man._name) // zky_man
console.log(Man.name) // zky_man
let People = new Proxy({_name:'zky'},{
  get:function(target,prop,receiver){ // receiver指向的是get的调用者
    return Reflect.get(target,prop,receiver) // 调用get name函数时,this被绑定到receiver
    }
  })
let Man = {
  _name:'zky_man',
  get name(){
    return this._name
  }
  }
Man.__proto__ = People // Man继承People
console.log(Man._name)// zky_man
console.log(Man.name) // zky_man

到这里问题就已经完美解决了,这也就是Reflect.gettarget[key]更好的原因。

调用Man.name时经过了以下几步

  1. proxy拦截,调用handler.get
  2. handler.get中传入的receiver参数指向调用者--Man
  3. 调用Reflect.get,由于target中的name指定了getterReflect.get自动将调用的getter函数的this绑定到receiver,也就是Man

如果没看懂请结合例子及上面对receiver参数的说明进行理解

参考文献:https://javascript.info/proxy?tdsourcetag=s_pctim_aiomsg#proxying-a-getter



作者:龙_猫
链接:https://www.jianshu.com/p/9ea14cdfd5b9
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值