pro-collection / interview-question

目标:收集全网经典面试问题
713 stars 53 forks source link

Reflect.get() 和直接通过对象 [.] 访问获取属性, 有何区别【热度: 225】 #1042

Open yanlele opened 1 month ago

yanlele commented 1 month ago

关键词:Reflect 函数

Reflect.get()和直接通过对象[.]访问获取属性有以下一些区别:

一、返回值

  1. Reflect.get()

    • 如果属性不存在,返回undefined
    • 例如:
      const obj = {};
      const value = Reflect.get(obj, "property");
      console.log(value); // undefined
  2. 对象直接访问:

    • 如果属性不存在,在非严格模式下返回undefined;在严格模式下,会抛出一个ReferenceError错误。
    • 例如:
      const obj = {};
      // 非严格模式下
      console.log(obj.property); // undefined
      // 严格模式下
      ("use strict");
      console.log(obj.property); // ReferenceError: property is not defined

二、可接受的参数和功能扩展

  1. Reflect.get()

    • 可以接受第三个参数receiver,用于指定属性访问的上下文对象,这在某些情况下非常有用,比如在使用代理时可以控制属性访问的行为。
    • 例如:
      const obj = { name: "John" };
      const proxy = new Proxy(obj, {});
      console.log(Reflect.get(proxy, "name", { name: "Jane" })); // 'Jane'
  2. 对象直接访问:

    • 没有类似的参数来指定上下文对象。

三、与代理的交互

  1. Reflect.get()

    • 与代理对象配合使用时,会触发代理对象上定义的相应拦截方法,使得可以对属性访问进行更精细的控制。
    • 例如:
      const obj = { name: "John" };
      const handler = {
      get(target, property, receiver) {
       if (property === "name") {
         return "Modified Name";
       }
       return Reflect.get(target, property, receiver);
      },
      };
      const proxy = new Proxy(obj, handler);
      console.log(proxy.name); // 'Modified Name'
  2. 对象直接访问:

    • 当通过直接访问属性的方式访问代理对象时,不一定会触发代理对象上的拦截方法,具体行为取决于代理的实现和配置。

四、一致性和规范性

  1. Reflect.get()

    • 作为一种更规范的方法,它与其他Reflect方法一起提供了一种统一的方式来进行对象操作,有助于提高代码的可读性和可维护性。
  2. 对象直接访问:

    • 虽然直接访问属性的方式更加简洁,但在一些复杂的场景下可能会导致不一致的行为,并且不太容易与其他高级特性(如代理)进行良好的集成。