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 和代理功能,写出更健壮的代码。

相关推荐
zhanghaha131429 分钟前
C# 系列教程_7 判断语句(分支)保姆级精讲
开发语言·c#
apcipot_rain33 分钟前
C++转Java日记(02)
java·开发语言·c++
杜 硕1 小时前
从零开始的C++生活——第七讲——02
开发语言·c++·生活
zhanghaha13141 小时前
C# 系列教程_8 循环语句 保姆级精讲(面向新手)
开发语言·c#
麦麦麦当劳大王9 小时前
【油猴脚本】Boss直聘 岗位职责复制
开发语言·前端·javascript
starzy199010 小时前
深入理解Scala Map:从实现原理到工程实践
开发语言·后端·scala
只睡四小时10 小时前
Three.js Sub-tick:漏判 60.7%→0
开发语言·javascript·性能优化·ecmascript·游戏开发·three.js·碰撞检测
码农小河6611 小时前
基于SSM+JSP的高校专业信息管理系统【附源码+数据库】
java·开发语言·数据库
excel11 小时前
基于 GPT 的自动发布文章接口方案:从一句话或一张图片生成并发布内容
前端·javascript·后端
东鹏特饮13 小时前
系统运维(传统/通用运维)面试题
开发语言·php