Skip to content

Reflect

TIP

  • Reflect 是 ES6 中引入的一个内置对象,它提供了一些反射方法,这些方法与那些在 Object 和 Function 原型上的方法具有相同的名称和功能。
  • Reflect 的引入主要是为了使操作对象的行为变得更规范和一致,并且提供一个与 Proxy 对象互补的 API。

一. Reflect 的方法

Reflect 定义

  • Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法
  • Reflect 不是一个构造函数,因此它是不能用 new 构造的

2 对象操作方法

(1) Reflect.get(target, propertyKey, receiver)

  • 用于查找并返回 target 对象的 propertyKey 属性
  • 相当于 target[propertyKey]

(2) Reflect.set(target, propertyKey, value, receiver)

  • 将 target 的 propertyKey 属性设置为 value。返回值为 boolean ,true 表示修改成功,false 表示失败。当 target 为不存在的对象时,会报错
  • 相当于 target[propertyKey] = value

(3) Reflect.deleteProperty(target, propertyKey)

  • 用于删除 target 对象的 propertyKey 属性,返回值为 boolean。如果 target 不是对象则会报错 TypeError
  • 相当于 delete target[propertyKey]

(4) Reflect.has(target, propertyKey)

  • 检查对象是否有某个属性
  • 相当于 propertyKey in target

(5) Reflect.defineProperty(target, propertyKey, attributes)

  • 用于为目标对象定义属性。如果 target 不是对象,会抛出错误
  • 相当于 Object.defineProperty(target, propertyKey, descriptor)

(6) Reflect.getOwnPropertyDescriptor(target, propertyKey)

  • 用于得到 target 对象的 propertyKey 属性的描述对象。在 target 不是对象时,会抛出错误表示参数非法,不会将非对象转换为对象
  • 相当于 Object.getOwnPropertyDescriptor(target, propertyKey)

(7) Reflect.ownKeys(target)

  • 用于返回 target 对象的所有自身的属性
  • 相当于 Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))。

3 函数调用方法

(1) Reflect.apply(target, thisArgument, argumentsList)

  • 调用一个函数
  • target 表示目标函数;thisArgument 表示目标函数绑定的 this 对象;argumentsList 表示目标函数调用时传入的参数列表,可以是数组或类似数组的对象。若目标函数无法调用,会抛出 TypeError
  • Function.prototype.apply.call(target, thisArgument, argumentsList)

(2) Reflect.construct(target, argumentsList[, newTarget])

  • 构造一个实例
  • 相当于 new target(...argumentsList)

4 原型操作方法

(1) Reflect.getPrototypeOf(target)

  • 用于读取 target 的 proto 属性。在 target 不是对象时不会像 Object 一样把 target 转为对象,而是会报错
  • 相当于 Object.getPrototypeOf(target)

(2) Reflect.setPrototypeOf(target, prototype)

  • 用于设置目标对象的 prototype
  • 相当于 Object.setPrototypeOf(target, prototype)

(3) Reflect.isExtensible(target)

  • 用于判断 target 对象是否可扩展。返回值为 boolean 。如果 target 参数不是对象,会抛出错误
  • 相当于 Object.isExtensible(target)

(4) Reflect.preventExtensions(target)

  • 用于让 target 对象变为不可扩展。如果 target 参数不是对象,会抛出错误
  • 相当于 Object.preventExtensions(target)

二. 具体示例

Reflect.get 和 Reflect.set

js
const obj = { a: 1 };

// 获取对象的属性值
console.log(Reflect.get(obj, "a")); // 1

// 设置对象的属性值
Reflect.set(obj, "b", 2);
console.log(obj.b); // 2

2 Reflect.deleteProperty

js
const obj = { a: 1, b: 2 };

// 删除对象的属性
Reflect.deleteProperty(obj, "a");
console.log(obj); // { b: 2 }

3 Reflect.has

js
const obj = { a: 1 };

// 检查对象是否有某个属性
console.log(Reflect.has(obj, "a")); // true
console.log(Reflect.has(obj, "b")); // false

4 Reflect.defineProperty

js
const obj = {};

// 定义对象的属性
Reflect.defineProperty(obj, "a", {
  value: 1,
  writable: true,
  enumerable: true,
  configurable: true,
});
console.log(obj.a); // 1

5 Reflect.apply

js
function sum(a, b) {
  return a + b;
}

// 调用函数
console.log(Reflect.apply(sum, undefined, [1, 2])); // 3

6 Reflect.construct

js
function Person(name) {
  this.name = name;
}

// 构造实例
const person = Reflect.construct(Person, ["John"]);
console.log(person.name); // John

7 Reflect.getPrototypeOf 和 Reflect.setPrototypeOf

js
const obj = { a: 1 };
const proto = { b: 2 };

// 获取对象的原型
console.log(Reflect.getPrototypeOf(obj)); // {}

// 设置对象的原型
Reflect.setPrototypeOf(obj, proto);
console.log(Reflect.getPrototypeOf(obj)); // { b: 2 }

Released under the MIT License.