Reflect

**Reflect** 命名空间对象包含用于调用可拦截 JavaScript 对象内部方法的静态方法。这些方法与 代理处理程序 的方法相同。

描述

与大多数全局对象不同,Reflect 不是构造函数。你不能将其与 new 运算符 一起使用,也不能将 Reflect 对象作为函数调用。Reflect 的所有属性和方法都是静态的(就像 Math 对象一样)。

Reflect 对象提供了一组静态函数,它们具有与 代理处理程序方法 相同的名称。

Reflect 的主要用例是在 Proxy 处理程序陷阱中提供默认转发行为。一个 陷阱 用于拦截对对象的某个操作——它为某个 对象内部方法 提供自定义实现。Reflect API 用于调用相应的内部方法。例如,下面的代码创建了一个代理 p,它具有一个 deleteProperty 陷阱,该陷阱拦截 [[Delete]] 内部方法。Reflect.deleteProperty() 用于直接在 targetObject 上调用默认的 [[Delete]] 行为。你可以用 delete 替换它,但使用 Reflect 可以让你不必记住每个内部方法对应的语法。

js
const p = new Proxy(
  {},
  {
    deleteProperty(targetObject, property) {
      // Custom functionality: log the deletion
      console.log("Deleting property:", property);

      // Execute the default introspection behavior
      return Reflect.deleteProperty(targetObject, property);
    },
  },
);

Reflect 方法还允许更精细地控制如何调用内部方法。例如,Reflect.construct() 是唯一一种使用特定 new.target 值来构造目标函数的方法。如果使用 new 运算符调用函数,new.target 值始终是该函数本身。这对于 子类化 有着重要的影响。另一个例子是 Reflect.get() 允许你使用自定义 this 值运行 getter,而 属性访问器 始终使用当前对象作为 this 值。

几乎每个 Reflect 方法的行为都可以用其他语法或方法来实现。其中一些方法在 Object 上具有相同名称的相应静态方法,尽管它们有一些细微的差异。有关确切的差异,请参阅每个 Reflect 方法的描述。

静态属性

Reflect[Symbol.toStringTag]

[Symbol.toStringTag] 属性的初始值为字符串 "Reflect"。此属性在 Object.prototype.toString() 中使用。

静态方法

Reflect.apply()

使用 argumentsList 参数指定的参数调用 target 函数。另请参阅 Function.prototype.apply()

Reflect.construct()

new 运算符 作为函数。等同于调用 new target(...argumentsList)。还提供了指定不同原型的选项。

Reflect.defineProperty()

类似于 Object.defineProperty()。返回一个布尔值,如果属性定义成功,则为 true

Reflect.deleteProperty()

delete 运算符 作为函数。等同于调用 delete target[propertyKey]

Reflect.get()

返回属性的值。作为函数,就像从对象获取属性(target[propertyKey])一样。

Reflect.getOwnPropertyDescriptor()

类似于 Object.getOwnPropertyDescriptor()。如果属性存在于对象上,则返回该属性的属性描述符,否则返回 undefined

Reflect.getPrototypeOf()

Object.getPrototypeOf() 相同。

Reflect.has()

返回一个布尔值,指示目标是否具有该属性。作为自身或继承的。作为函数,就像 in 运算符 一样。

Reflect.isExtensible()

Object.isExtensible() 相同。返回一个布尔值,如果目标是可扩展的,则为 true

Reflect.ownKeys()

返回目标对象自身(非继承)属性键的数组。

Reflect.preventExtensions()

类似于 Object.preventExtensions()。返回一个布尔值,如果更新成功,则为 true

Reflect.set()

一个为属性赋值的函数。返回一个布尔值,如果更新成功,则为 true

Reflect.setPrototypeOf()

一个设置对象原型的函数。返回一个布尔值,如果更新成功,则为 true

示例

检测对象是否包含某些属性

js
const duck = {
  name: "Maurice",
  color: "white",
  greeting() {
    console.log(`Quaaaack! My name is ${this.name}`);
  },
};

Reflect.has(duck, "color");
// true
Reflect.has(duck, "haircut");
// false

返回对象的自身键

js
Reflect.ownKeys(duck);
// [ "name", "color", "greeting" ]

向对象添加新属性

js
Reflect.set(duck, "eyes", "black");
// returns "true" if successful
// "duck" now contains the property "eyes: 'black'"

规范

规范
ECMAScript 语言规范
# sec-reflect-object

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅