Reflect 是将 JavaScript 引擎隐式内部操作(如[[Get]]、[[Set]])显式暴露为可编程、可拦截函数的工具,统一错误处理、提升安全性与可控性,并天然适配 Proxy。

Reflect 不是“调用对象内部方法”的工具,而是把 JavaScript 引擎原本隐式执行的内部操作(如 [[Get]]、[[Set]]、[[Construct]])暴露为可编程、可判断、可拦截的函数。它不提供额外能力,但让这些操作变得统一、显式、可控。
用 Reflect.get/set 替代点号和赋值,避免静默失败
传统写法 obj.name 或 obj.x = 1 在出错时行为不一致:读取 null 的属性直接报错,赋值给只读属性却返回值却不提示失败。Reflect 把它们变成可判断的函数:
-
安全读取:用
Reflect.get(obj, 'name'),即使obj是null或undefined,也只返回undefined,不抛异常 -
明确赋值结果:用
Reflect.set(obj, 'count', 42),成功返回true,失败(如属性不可写、目标非对象)返回false,便于做条件分支 -
绑定 receiver:当属性是 getter/setter 时,第三个参数可传入正确上下文,确保内部
this指向准确
用 Reflect.defineProperty 等替代 Object 方法,统一错误反馈
Object 上很多方法失败就抛错,而 Reflect 版本统一返回布尔值,更适合防御性编程:
-
Reflect.defineProperty(obj, 'id', { value: 1 })失败时不抛错,返回false,可直接用于if判断 -
Reflect.deleteProperty(obj, 'age')返回true/false,比delete obj.age更可靠(后者对不可配置属性也返回true) -
Reflect.has(obj, 'x')行为等价于'x' in obj,但作为函数更易组合、测试和 mock
用 Reflect.apply/construct 替代 apply/new,语义更清晰
函数调用和构造实例这类操作过去依赖原型方法或语法糖,Reflect 提供了标准、无歧义的函数形式:
立即学习“Java免费学习笔记(深入)”;
-
Reflect.apply(fn, thisCtx, [a, b])明确表达“以某上下文、某参数列表执行函数”,比fn.apply(thisCtx, [a,b])更函数式,也更容易封装(如加 try/catch、日志) -
Reflect.construct(Cls, [arg1], SubCls)支持指定构造器原型链,比new Cls(arg1)更灵活,适合实现自定义 new 行为 - 二者都要求参数完整、类型合规(如
argumentsList必须是类数组),提前暴露问题,而非运行时意外崩溃
与 Proxy 配合,自然转发默认行为
Reflect 最自然的使用场景是在 Proxy handler 中——每个 trap 名称都与一个 Reflect 方法同名,签名一致:
- 在
get(target, key, receiver)trap 中调用Reflect.get(target, key, receiver),既保留原始语义,又不会遗漏 receiver 绑定或原型链查找逻辑 - 在
set、has、ownKeys等 trap 中同理,避免手动模拟内部算法,减少 bug - 这种组合让拦截逻辑专注业务(如权限校验、日志记录),底层操作交给 Reflect 保证正确性


















