ES6 Reflect 对象的用途

理解 Reflect 对象的设计目的和使用场景

问题

ES6 中的 Reflect 对象有什么用?

解答

Reflect 是 ES6 新增的内置对象,不是构造函数,不能使用 new 操作符。它的设计目的主要有以下几点:

1. 统一语言内部方法

将 Object 对象上属于语言内部的方法迁移到 Reflect 对象上,比如 Object.defineProperty。现阶段这些方法在两个对象上都存在,但未来新方法只会部署在 Reflect 上。

2. 让操作返回更合理的结果

修改某些 Object 方法的返回值,使其更易用。例如:

  • Object.defineProperty(obj, name, desc) 失败时会抛出错误
  • Reflect.defineProperty(obj, name, desc) 失败时返回 false

3. 将命令式操作改为函数式

让所有对象操作都变成函数调用:

  • name in objReflect.has(obj, name)
  • delete obj[name]Reflect.deleteProperty(obj, name)

4. 配合 Proxy 使用

Reflect 的方法与 Proxy 的拦截方法一一对应,可以在 Proxy 中方便地调用默认行为:

var loggedObj = new Proxy(obj, {
  get(target, name) {
    console.log("get", target, name);
    return Reflect.get(target, name);
  },
  deleteProperty(target, name) {
    console.log("delete " + name);
    return Reflect.deleteProperty(target, name);
  }
});

上面代码中,Proxy 拦截操作后调用对应的 Reflect 方法保证原生行为正常执行,同时添加日志输出功能。

关键点

  • Reflect 不是构造函数,提供静态方法访问语言内部操作
  • 方法返回值更合理,失败返回 false 而非抛出错误
  • 将命令式操作(indelete)转为函数调用
  • 与 Proxy 方法一一对应,方便在拦截器中调用默认行为