Reflect 是 JavaScript 中的一个内置对象,它提供了一组静态方法,用于执行与对象操作相关的底层功能(如属性访问、函数调用、构造函数调用等)。这些方法与 Object 或 Proxy 的方法类似,但设计更一致且适合与 Proxy 配合使用。以下是 Reflect 的核心用法和常见场景:
1. 基本方法列表
Reflect 的方法与 Proxy 的陷阱方法一一对应,常用方法包括:
| 方法 | 作用 | 示例 |
|---|---|---|
Reflect.get(target, prop, receiver) |
获取对象属性 | Reflect.get({a: 1}, 'a') → 1 |
Reflect.set(target, prop, value, receiver) |
设置对象属性 | Reflect.set({}, 'a', 2) → true |
Reflect.has(target, prop) |
检查属性是否存在(类似 in) |
Reflect.has({a: 1}, 'a') → true |
Reflect.deleteProperty(target, prop) |
删除属性(类似 delete) |
Reflect.deleteProperty({a: 1}, 'a') → true |
Reflect.construct(target, args) |
调用构造函数 | Reflect.construct(Date, [2023]) → Date 实例 |
Reflect.apply(func, thisArg, args) |
调用函数 | Reflect.apply(Math.max, null, [1, 2]) → 2 |
Reflect.ownKeys(target) |
获取所有自身键(包括 Symbol) | Reflect.ownKeys({a: 1, [Symbol()]: 2}) → ['a', Symbol()] |
2. 核心使用场景
(1) 替代操作符或 Object 方法
// 传统方式 vs Reflect
obj.a = 1; // → Reflect.set(obj, 'a', 1)
'a' in obj; // → Reflect.has(obj, 'a')
new Date(2023); // → Reflect.construct(Date, [2023])
Math.max.apply(null, [1, 2]); // → Reflect.apply(Math.max, null, [1, 2])
(2) 与 Proxy 配合使用
Reflect 方法通常用于 Proxy 陷阱中,保持默认行为:
const proxy = new Proxy({ a: 1 }, {
get(target, prop, receiver) {
console.log(`Getting ${prop}`);
return Reflect.get(target, prop, receiver); // 保持默认行为
}
});
proxy.a; // 输出 "Getting a",返回 1
(3) 更安全的操作
Reflect 方法返回布尔值或结果,避免抛出错误(如 defineProperty 失败时返回 false 而非报错):
// Object.defineProperty 失败会抛出错误
try {
Object.defineProperty({}, 'a', { value: 1, writable: false });
Object.defineProperty({}, 'a', { value: 2 }); // 报错
} catch (e) {
console.error(e);
}
// Reflect.defineProperty 返回布尔值
const success = Reflect.defineProperty({}, 'a', { value: 1 });
if (!success) console.log('Failed to define property');
3. 实际示例
(1) 日志拦截
const loggedObj = new Proxy({ a: 1 }, {
set(target, prop, value, receiver) {
console.log(`Setting ${prop} to ${value}`);
return Reflect.set(target, prop, value, receiver);
}
});
loggedObj.b = 2; // 输出 "Setting b to 2"
(2) 验证属性赋值
const validatedObj = new Proxy({ age: 0 }, {
set(target, prop, value) {
if (prop === 'age' && typeof value !== 'number') {
throw new TypeError('Age must be a number');
}
return Reflect.set(target, prop, value);
}
});
validatedObj.age = 30; // 正常
validatedObj.age = '30'; // 抛出 TypeError
(3) 动态调用构造函数
function createInstance(Constructor, ...args) {
return Reflect.construct(Constructor, args);
}
const date = createInstance(Date, 2023, 0, 1); // 等价于 new Date(2023, 0, 1)
4. 注意事项
- 返回值一致性:
Reflect方法总是返回操作结果(如Reflect.set返回布尔值,而直接赋值无返回值)。 - 与 Proxy 的对称性:
Proxy的陷阱方法(如get、set)通常需要调用对应的Reflect方法以保持默认行为。 - 替代旧方法:
Reflect可以替代Object.defineProperty、Function.prototype.apply等传统方式。
通过 Reflect,JavaScript 的元编程(如 Proxy)变得更加清晰和可靠。建议在需要底层对象操作或编写 Proxy 处理器时优先使用它。
前端工程师、程序员

浙公网安备 33010602011771号