反射

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

¥The Reflect namespace object contains static methods for invoking interceptable JavaScript object internal methods. The methods are the same as those of proxy handlers.

描述

¥Description

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

¥Unlike most global objects, Reflect is not a constructor. You cannot use it with the new operator or invoke the Reflect object as a function. All properties and methods of Reflect are static (just like the Math object).

Reflect 对象提供了与 代理处理程序方法 同名的静态函数集合。

¥The Reflect object provides a collection of static functions which have the same names as the proxy handler methods.

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

¥The major use case of Reflect is to provide default forwarding behavior in Proxy handler traps. A trap is used to intercept an operation on an object — it provides a custom implementation for an object internal method. The Reflect API is used to invoke the corresponding internal method. For example, the code below creates a proxy p with a deleteProperty trap that intercepts the [[Delete]] internal method. Reflect.deleteProperty() is used to invoke the default [[Delete]] behavior on targetObject directly. You can replace it with delete, but using Reflect saves you from having to remember the syntax that each internal method corresponds to.

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 值始终是函数本身。这对 subclassing 有重要影响。再例如,Reflect.get() 允许你使用自定义 this 值运行 getter,而 属性访问器 始终使用当前对象作为 this 值。

¥The Reflect methods also allow finer control of how the internal method is invoked. For example, Reflect.construct() is the only way to construct a target function with a specific new.target value. If you use the new operator to invoke a function, the new.target value is always the function itself. This has important effects with subclassing. For another example, Reflect.get() allows you to run a getter with a custom this value, while property accessors always use the current object as the this value.

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

¥Nearly every Reflect method's behavior can be done with some other syntax or method. Some of these methods have corresponding static methods of the same name on Object, although they do have some subtle differences. For the exact differences, see the description for each Reflect method.

静态属性

¥Static properties

Reflect[Symbol.toStringTag]

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

静态方法

¥Static methods

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

示例

¥Examples

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

¥Detecting whether an object contains certain properties

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

返回对象自己的键

¥Returning the object's own keys

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

向对象添加新属性

¥Adding a new property to the object

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

规范

Specification
ECMAScript Language Specification
# sec-reflect-object

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看

¥See also