Reflect是ES6新增的内置对象,提供13个静态方法(如get、set、construct等),统一规范对象操作,返回明确布尔值或结果,不抛错,且与Proxy trap一一对应,便于元编程和默认行为转发。

Reflect 是 ES6 引入的一个内置对象,它提供了一组静态方法,用于更规范、更函数式地操作对象(比如读取属性、设置属性、调用构造函数等)。它的设计初衷是把原本分散在 Object、Function、Proxy 等地方的操作统一起来,并与 Proxy 的 trap 方法一一对应,方便元编程和拦截逻辑复用。
Reflect 常用方法及典型用法
Reflect 的方法大多返回布尔值或操作结果,失败时不会抛错(比如 Reflect.get 不会因属性不存在而报错,而是返回 undefined),这点比直接用点号或中括号访问更安全。
-
Reflect.get(target, key, receiver):读取属性。receiver 用于指定 this 上下文(尤其在 getter 中有用)。
例如:Reflect.get(obj, 'name')等价于obj.name,但支持动态 key 和 receiver 控制。 -
Reflect.set(target, key, value, receiver):设置属性,返回 true/false 表示是否成功(注意:严格模式下对不可写属性赋值会返回 false,而非抛错)。
例如:Reflect.set(obj, 'age', 30)比obj.age = 30更易捕获失败。 -
Reflect.has(target, key):检查属性是否存在(相当于
key in target),但更语义清晰且可被 Proxy 拦截。 -
Reflect.deleteProperty(target, key):删除属性,返回布尔值(类似
delete target[key],但更一致)。 -
Reflect.construct(target, args, newTarget?):替代 new 操作符调用构造函数,支持指定 new.target(对继承场景友好)。
例如:Reflect.construct(Date, [2023, 0, 1])相当于new Date(2023, 0, 1)。
Reflect 和 Proxy 配合使用
Reflect 方法名和 Proxy handler 的 trap 完全一致(如 get/set/has/construct),因此在 Proxy 中推荐用 Reflect 转发操作,避免重复实现,也保证默认行为一致。
例如写一个日志代理:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
立即学习“Java免费学习笔记(深入)”;
const proxy = new Proxy(obj, {
get(target, key, receiver) {
console.log(`读取 ${key}`);
return Reflect.get(target, key, receiver); // 转发到原行为
},
set(target, key, value, receiver) {
console.log(`设置 ${key} = ${value}`);
return Reflect.set(target, key, value, receiver);
}
});
为什么不用 Object 或操作符?
直接用 obj[key] 或 obj.key 简单直观,但 Reflect 提供了三点关键价值:
- 所有方法都返回明确的结果(true/false 或值),便于统一判断和错误处理;
- 方法调用是函数式风格,适合高阶操作(如 map、filter 属性名时传入 Reflect.has);
- 与 Proxy 深度协同,让拦截逻辑既可定制又可安全回退到默认行为。
注意事项
Reflect 本身不可构造、不可遍历,所有方法都是静态的;它不提供新能力,而是封装和标准化已有能力。不是必须用,但在需要健壮性、可拦截性或统一接口时特别实用。

















