let obj = { foo: 1 };为什么Reflect.get(obj, ‘foo‘, { foo: 2 }); // 输出 1?

理解 JavaScript 的 Reflect.get() 方法及其 receiver 参数

结论:receiver 不会影响属性的查找过程。,receiver只会影响this的绑定

Reflect.get() 是 JavaScript 中一个强大的反射 API,它允许我们以编程方式获取对象的属性值。虽然看起来简单,但它的第三个参数 receiver 却有一些容易被忽略的细节。

基本用法

Reflect.get() 的基本语法是:

javascript 复制代码
Reflect.get(target, propertyKey[, receiver])

最简单的用法是获取对象的属性值:

javascript 复制代码
const obj = { foo: 1 };
console.log(Reflect.get(obj, 'foo')); // 输出 1

receiver 参数的误区

很多开发者(包括我自己最初)会认为 receiver 参数可以覆盖属性值:

javascript 复制代码
const obj = { foo: 1 };
console.log(Reflect.get(obj, 'foo', { foo: 2 })); // 输出 1,不是 2!

为什么不是 2?​

因为对于普通的数据属性,receiver 不会影响属性的查找过程。Reflect.get() 会直接从 target 对象上查找属性。

receiver 的真正作用

receiver 参数主要影响 getter 函数中的 this 绑定:

javascript 复制代码
const obj = {
  get foo() {
    return this.bar;
  },
  bar: 1
};

const receiver = { bar: 2 };

console.log(Reflect.get(obj, 'foo'));       // 输出 1 (this 指向 obj)
console.log(Reflect.get(obj, 'foo', receiver)); // 输出 2 (this 指向 receiver)

在这个例子中,receiver 改变了 getter 函数执行时的 this 值,因此返回了不同的结果。

实际应用场景

  1. 代理 getter 函数​:

    javascript 复制代码
    const obj = {
      get name() {
        return this._name.toUpperCase();
      }
    };
    
    const proxy = new Proxy(obj, {
      get(target, prop, receiver) {
        console.log(`Getting ${prop}`);
        return Reflect.get(target, prop, receiver);
      }
    });
    
    const child = { _name: 'Alice' };
    Object.setPrototypeOf(child, proxy);
    
    console.log(child.name); 
    // 输出: "Getting name" 然后 "ALICE"
  2. 继承场景​:

    javascript 复制代码
    class Parent {
      get greeting() {
        return `Hello, ${this.name}`;
      }
    }
    
    class Child extends Parent {
      constructor(name) {
        super();
        this.name = name;
      }
    }
    
    const child = new Child('Bob');
    console.log(Reflect.get(Parent.prototype, 'greeting', child)); // "Hello, Bob"

总结

  • 对于普通属性,receiver 不会影响属性查找结果
  • 对于 getter 函数,receiver 决定了函数中 this 的值
  • 在代理和继承场景中,正确使用 receiver 可以保持 this 绑定的正确性

理解 Reflect.get()receiver 参数有助于我们更好地使用 JavaScript 的反射 API 和代理功能,写出更健壮的代码。

相关推荐
ssshooter4 小时前
看完就懂 useSyncExternalStore
前端·javascript·react.js
Live000005 小时前
在鸿蒙中使用 Repeat 渲染嵌套列表,修改内层列表的一个元素,页面不会更新
前端·javascript·react native
柳杉5 小时前
使用Ai从零开发智慧水利态势感知大屏(开源)
前端·javascript·数据可视化
球球pick小樱花6 小时前
游戏官网前端工具库:海内外案例解析
前端·javascript·css
喝水的长颈鹿6 小时前
【大白话前端 02】网页从解析到绘制的全流程
前端·javascript
用户14536981458786 小时前
VersionCheck.js - 让前端版本更新变得简单优雅
前端·javascript
codingWhat6 小时前
整理「祖传」代码,就是在开发脚手架?
前端·javascript·node.js
码路飞6 小时前
写了个 AI 聊天页面,被 5 种流式格式折腾了一整天 😭
javascript·python
Lee川6 小时前
优雅进化的JavaScript:从ES6+新特性看现代前端开发范式
javascript·面试
颜酱7 小时前
单调队列:滑动窗口极值问题的最优解(通用模板版)
javascript·后端·算法