实用反射 API

123 阅读1分钟

实用反射 API

  • 某些情况下应该优先使用反射 API,这是有一些理由的。
  1. 反射 API 与对象 API
    在使用反射 API 时,要记住:
    (1). 反射 API 并不限于捕获处理程序;
    (2). 大多数反射 API 方法在 Object 类型上有对应的方法。
    通常,Object 上的方法适用通用程序,而反射方实用于细粒度的对象控制与操作。

  2. 状态标记
    很多反射方法返回称作 “状态标记” 的布尔值,表示意图执行的操作是否成功。有时候,状态标记比那些返回修改后的对象或者抛出错误(取决于方法)的反射 API 方法更有用。例如可以使用反射 API 对下面代码进行重构:

    // 初始代码
    const o = {};
    try {
      Object, defineProperty(o, "foo", "bar");
      console.log("success");
    } catch (e) {
      console.log("failure");
    }
    

    在定义新属性时如果发生问题,Reflect.defineProperty()会返回 false, 而不是抛出错误。因此可以使用这个反射方法进行重构:

    const o = {};
    if (Reflect.defineProperty(o, "foo", { value: "bar" })) {
      console.log("success");
    } else {
      console.log("failure");
    }
    
  3. 用一等函数替代操作符
    以下反射方法提供只有通过操作符才能完成的操作。
    Reflect.get():可以替代对象属性访问操作符。
    Reflect.set():可以替代=赋值操作符。
    Reflect.has(): 可以替代 in 操作符或 with()。
    Reflect.deleteProperty():可以替代 delete 操作符。
    Reflect.construct():可以替代 new 操作符。

  4. 安全地应用函数
    在通过 apply 方法调用函数时,被调用的函数可能也定义了自己的 apply 属性,为绕这个问题,可以使用定义在 Function 原型上的 apply 方法,

    Function.prototype.apply.call(myFunc, thisVal, argumentList);
    //这种可怕的代码可以使用Reflect.apply()老避免;
    Reflect.apply(myFunc, thisVal, argumentList);