Proxy和Reflect中的receiver到底是个什么东西

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情

ProxyReflect对象中的getset方法的第三个参数是receiver,今天本文将讲述这个receiver到底是什么?

receiver翻译过来是接收者的意思,我们先看下MDN怎么解释这个参数的

proxy get receiver

Proxy或者继承Proxy的对象

当目前属性是一个getter访问器属性,通常情况下receiver参数为当前proxy本身。那么什么情况下receiver不是proxy本身?

我们先看一个简单的Proxy栗子,下面这个栗子我们使用了getter捕获器中的receiver参数。

let obj ={a:1}

let pObj=new Proxy(obj,{
    get(target,key,receiver){
        console.log("receiver",receiver); // receiver  Proxy {a:1}
        console.log("receiver===pObj",receiver===pObj); // true
        return Reflect.get(target,key)
    }
})

console.log(pObj.a); // 1
复制代码

从这个栗子中可以得出当前receiver参数是当前代理对象。

我们再看看另外一个当Proxy对象被继承时的栗子

let obj ={a:1}

var pObj=new Proxy(obj,{
    get(target,key,receiver){
        return receiver
    }
})

console.log(pObj.getReceiver); // pObj {a: 1}

let child = Object.create(pObj);
console.log(child.getReceiver); // child {}
复制代码

child对象被继承于pObj对象时,receiver参数会自动指向到继承它的对象。

到了这个我们已经这个Proxy中的receiver参数是什么了,接着我们看看Reflect中的receiver参数。

我们拿上面第一个栗子修改一下,把Reflect.get的第一个参数改为receiver,也即是当触发getter函数时,从receiver中获取对应的属性值。

let obj ={a:1}

let pObj=new Proxy(obj,{
    get(target,key,receiver){
        return Reflect.get(receiver,key)
    }
})

console.log(pObj.a); 
复制代码

Uncaught RangeError: Maximum call stack size exceeded

细心的同学会发现这一段代码是一个死循环,在通过pObj.a时,触发了getter属性,又继续访问了receiver中的getter....一直嵌套下去导致无限循环。

这个时候就要Reflect.get的第三个参数传入Proxy中的receiver参数了,我们纠正下上面的代码。

let obj ={a:1}

let pObj=new Proxy(obj,{
    get(target,key,receiver){
        return Reflect.get(target,key,receiver)
    }
})

console.log(pObj.a); // 1
复制代码

这里的Reflect.get中的receiver参数是target对象中getter调用时的this值,这么说可能不是很明白,我们再通过一个栗子看看。

const obj = { get a() { return this.b; } };
const proxy = new Proxy(obj, {
    get(target, key) {
        return target[key]
    }
})

console.log(Reflect.get(obj, "a")); // undefined
console.log(Reflect.get(obj, "a", { b: 2 })); // 2
复制代码

在这里栗子中,我们给obj对象上设置了一个getter属性a,当我们访问a时返回当前this中的b,这里可以看到b是没有被定义的,直接访问为undefined,我们使用Reflect第三个参数receiver绑定a的this值为{ b: 2 },最终可以访问得到2

猜你喜欢

转载自juejin.im/post/7085742282476879902