Reflect.get第三个参数recevier的作用

问题

Reflect.get三个参数target, key, receiver,前两个好理解,第三个是什么意思呢?哪些场景下会用到呢?本文尝试解释下这个问题。

解释

首先搬出MDN对应Reflect.get第三个参数recevier的解释:

Reflect(target, key, recevier)中,如果target对象中指定了getterreceiver则为getter调用时的this值。

我们先定一个原始对象obj

js 复制代码
const obj = {
    hello: 1
}

根据MDN的描述,receiver是用来指定原始对象中getterthis 。因此obj需要增加一个getter属性world,同时在getter方法使用this

js 复制代码
const obj = {
    hello: 1,
    get world() {
        return this.hello
    }
}

console.log(obj.world) // 1

这样一个符合条件的原始对象例子有了。访问obj.world输出1。

那下面的代码呢?

js 复制代码
const obj2 = {
    hello: 2
}
console.log(Reflect.get(obj, 'world', obj2)); // 2

结果返回的是2。这里解释下原因:

  1. 当前Reflect.getreceiverobj2obj2有一个属性hello为2;
  2. 根据MDN的描述,receivergetter调用的this值,因此objgetter属性的this指向obj2
  3. 当读取objworld属性时,返回this.hello,因此返回的为obj2hello值。

使用场景

通常在Proxy中我们如下返回原始对象的属性值:

js 复制代码
const pObj = new Proxy(obj, {
    get(target, key, receiver) {
        console.log('Proxy key:', key)
        return target[key]
    }
})

pObj.world; // 读取代理对象的world属性

// 输出
// Proxy key: world

因为读取了pObj的属性world,因此会进入到get方法,所以输出如上。

当然我们也可以通过Reflect.get返回属性值:

js 复制代码
const pObj = new Proxy(obj, {
    get(target, key, receiver) {
        console.log('Proxy key:', key)
        return Reflect.get(target, key, receiver)
    }
})

pObj.world; // 读取代理对象的world属性

// 输出
// Proxy key: world
// Proxy key: hello

通过Reflect.get的调用,多输出了一行hello。原因如下:

  1. 首先得知道下Proxy中的get方法中也有一个reciever,根据MDN的描述。它表示的就是当前的Proxy对象pObj
  2. 因此Reflect.get(target, key, receiver)等价于Reflect.get(target, key, pObj),读取world的时候的时候,返回this.hello,当前的this又指代的是pObj,因此读取了pObj.hello
  3. pObj.hello的读取再次进入了代理对象的get方法中,因此输出了第二行的hello

通过上面两种方式的对比,可以知道,如果使用target[key]的方法返回属性值,我们无法拦截到this.hello的读取操作;而通过Reflect.get则可以。

总结

  1. Reflect.get(target, key, receiver)方法中,receiver指代target对象中getter属性的this值。
  2. 相关代码:github.com/wdskuki/js-...
相关推荐
majingming1236 小时前
FUNCTION
java·前端·javascript
A_nanda7 小时前
Vue项目升级
前端·vue3·vue2
SuperEugene7 小时前
Axios 接口请求规范实战:请求参数 / 响应处理 / 异常兜底,避坑中后台 API 调用混乱|API 与异步请求规范篇
开发语言·前端·javascript·vue.js·前端框架·axios
abigale038 小时前
【浏览器 API / 网络请求 / 文件处理】前端文件上传全流程:从基础上传到断点续传
前端·typescript·文件上传·vue cli
Setsuna_F_Seiei8 小时前
AI 对话应用之页面滚动交互的实现
前端·javascript·ai编程
新缸中之脑8 小时前
追踪来自Agent的Web 流量
前端
wefly20179 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
英俊潇洒美少年9 小时前
vue如何实现react useDeferredvalue和useTransition的效果
前端·vue.js·react.js
kyriewen1110 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript
英俊潇洒美少年10 小时前
react19和vue3的优缺点 对比
前端·javascript·vue.js·react.js