myfreax

JavaScript Reflect 反射

在计算机编程中,反射是程序在运行时操作对象的变量、属性和方法的能力,在 ES6 引入 Reflect 的全局对象为 JavaScript 提供这种能力

JavaScript Reflect 反射
JavaScript Reflect 反射

在本教程中,您将了解 JavaScript ES6 的反射和 Reflect API。

什么是反射

在计算机编程中,反射是程序在运行时操作对象的变量、属性和方法的能力。

在 ES6 之前,JavaScript 已经具有反射功能,尽管社区或规范并未正式称呼它们。例如,Object.keys()Object.getOwnPropertyDescriptor()Array.isArray() 等方法是经典的反射特性。

ES6 引入一个名为 Reflect 的全局对象,它允许您调用方法、构造对象、获取和设置属性、操作和扩展属性。

Reflect API 非常重要,因为它允许您开发能够处理动态代码的程序和框架。

反射 API

与大多数全局对象不同,Reflect 不是构造函数。这意味着您不能将 new 运算符用于 Reflect 或者将其 Reflect 作为函数调用。它类似于 MathJSON 对象。Reflect 对象的所有方法都是静态方法。

  • Reflect.apply() – 使用指定参数调用函数
  • Reflect.construct() – 像 new 运算符一样工作,但是作为一个函数。相当于调用 new target(...args)
  • Reflect.defineProperty() – 与 Object.defineProperty() 类似,但返回一个布尔值,指示该属性是否在对象上成功定义。
  • Reflect.deleteProperty() – 行为类似于 delete 运算符,但作为函数。相当于调用 delete objectName[propertyName]
  • Reflect.get() – 返回属性的值。
  • Reflect.getOwnPropertyDescriptor() – 类似于Object.getOwnPropertyDescriptor()。如果该属性存在于对象上,则它返回该属性的属性描述符,否则返回 undefined
  • Reflect.getPrototypeOf() – 与 Object.getPrototypeOf() 相同。
  • Reflect.has() – 像 in 操作符一样工作,但是作为一个函数。它返回一个布尔值,指示属性是否存在。
  • Reflect.isExtensible() – 与 Object.isExtensible() 相同。
  • Reflect.ownKeys() – 返回对象拥有的属性键(不包括继承的)的数组。
  • Reflect.preventExtensions() – 类似于 Object.preventExtensions() 它返回一个布尔值。
  • Reflect.set() – 为属性赋值并返回一个布尔值,如果属性设置成功则返回 true。
  • Reflect.setPrototypeOf() – 设置对象的原型

Reflect.construct 创建对象

Reflect.construct() 方法的行为类似于 new 运算符,但作为函数。它相当于调用new target(...args) 并可以指定不同的原型对象:

Reflect.construct(target, args [, newTarget]) 

Reflect.construct() 返回 target 的实例,如果指定 newTarget,则由 target 的构造函数和指定的类数组对象参数进行初始化。例如以下示例:

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    get fullName() {
        return `${this.firstName} ${this.lastName}`;
    }
};

let args = ['John', 'Doe'];

let john = Reflect.construct(
    Person,
    args
);

console.log(john instanceof Person);
console.log(john.fullName); // John Doe

输出

true
John Doe

在这个例子中:

  • 首先,定义一个名为 Person 的类。
  • 其次,声明一个包含两个字符串的数组 args
  • 第三,使用 Reflect.construct() 方法创建 Person 类的新实例。john 对象是Person 类的实例,因此它具有属性 fullName

Reflect.apply 调用函数

在 ES6 之前,您可以使用 Function.prototype.apply() 方法指定 this 值和 arguments 调用函数来。例如:

let result = Function.prototype.apply.call(Math.max, Math, [10, 20, 30]);
console.log(result);

输出:

30

这个语法相当冗长。

Reflect.apply() 提供与 Function.prototype.apply() 相同的功能,但更简洁且更易于理解:

let result = Reflect.apply(Math.max, Math, [10, 20, 30]);
console.log(result);

Reflect.apply() 方法的语法如下:

Reflect.apply(target, thisArg, args)

Reflect.defineProperty 定义属性

Reflect.defineProperty() 就像 Object.defineProperty() 一样。但是,它返回一个布尔值,指示该属性是否已成功定义,而不是抛出异常:

Reflect.defineProperty(target, propertyName, propertyDescriptor)

例如示例:

let person = {
    name: 'John Doe'
};

if (Reflect.defineProperty(person, 'age', {
        writable: true,
        configurable: true,
        enumerable: false,
        value: 25,
    })) {
    console.log(person.age);
} else {
    console.log('Cannot define the age property on the person object.');

}

结论

在本教程中,您已了解 JavaScript 反射和 Reflect API 的方法 。

内容导航