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

相关推荐
云知谷7 分钟前
【HTML】网络数据是如何渲染成HTML网页页面显示的
开发语言·网络·计算机网络·html
可触的未来,发芽的智生29 分钟前
新奇特:黑猫警长的纳米世界,忆阻器与神经网络的智慧
javascript·人工智能·python·神经网络·架构
lly2024061 小时前
SQL ROUND() 函数详解
开发语言
大宝剑1701 小时前
python环境安装
开发语言·python
前端开发爱好者1 小时前
尤雨溪官宣:"新玩具" 比 Prettier 快 45 倍!
前端·javascript·vue.js
欧阳呀1 小时前
Vue+element ui导入组件封装——超级优雅版
前端·javascript·vue.js·elementui
lly2024061 小时前
CSS3 多媒体查询
开发语言
天***88962 小时前
js封装一个双精度算法实现
开发语言·前端·javascript
.小小陈.2 小时前
数据结构2:单链表
c语言·开发语言·数据结构·笔记·学习方法