Reflect是ES6引入的静态方法集合,用于显式暴露JavaScript底层操作;它提供统一返回值、支持Proxy拦截、填补语法空白(如construct),但不可构造,日常开发中非必需。
Reflect 不是语法糖,也不是新对象构造器,它是 ES6 引入的一组静态方法集合,用来统一、显式地暴露 JavaScript 的底层操作——本质上,它是对原本隐式发生的对象行为(比如 obj[key]、delete obj.key)的“可编程接口”。
很多 Reflect 方法看起来和已有语法重复,比如 Reflect.get(obj, key) 看似等价于 obj[key],但关键差异在于:
Reflect 方法都返回明确的值(成功返回结果,失败返回 false 或抛错),而部分操作符在严格模式下会静默失败或抛出类型错误Proxy 的 trap 名称完全一致,方便在代理中转发操作:get(target, key, receiver) { return Reflect.get(target, key, receiver); }
Reflect.construct() 是唯一能指定 new.target 的方式;Reflect.apply() 比 func.apply() 更底层、不依赖函数自身实现以下是高频、有实际替代价值的几个方法,注意参数顺序和返回约定:
Refle
ct.get(target, key, receiver):支持访问器属性、正确处理 this 绑定(receiver 即调用时的 this)Reflect.set(target, key, value, receiver):返回布尔值表示是否成功(区别于赋值表达式永远返回值),可用于拦截写入逻辑Reflect.has(obj, key):等价于 key in obj,但可被 Proxy 拦截,且不触发原型链上的 hasOwnProperty 误判Reflect.deleteProperty(obj, key):返回布尔值,比 delete obj.key 更可控(后者在严格模式下对不可配置属性会抛错)Reflect.ownKeys(obj):返回包括 Symbol 的所有自有属性键,比 Object.keys() 和 Object.getOwnPropertyNames() 更完整const obj = { a: 1 };
Object.defineProperty(obj, 'b', {
get() { return this.a * 2; },
configurable: false
});
// 直接访问 b 会触发 getter,但无法控制 receiver
console.log(obj.b); // 2
// 用 Reflect.get 可显式传入 receiver(比如另一个对象)
const proxyReceiver = { a: 10 };
console.log(Reflect.get(obj, 'b', proxyReceiver)); // 20
Reflect 不是构造函数,不能 new Reflect();所有方法必须通过 Reflect.xxx() 调用。常见误区:
Reflect.apply(func, thisArg, argsList) 的第三个参数必须是数组(或类数组),不是展开的参数 —— Reflect.apply(fn, null, [1,2]) ✅,Reflect.apply(fn, null, 1, 2) ❌Reflect.set() 在非严格模式下对不可写属性返回 false,但不会报错;而 obj.prop = val 会静默失败(无提示)Reflect.enumerate() 已被移除(ES2016 起废弃),不要在新代码中使用;遍历请用 Reflect.ownKeys() + for...of 或 Object.keys()
真正需要 Reflect 的地方,往往出现在写 Proxy、做属性访问抽象、或需要稳定返回值的元编程场景里;日常业务代码里硬套 Reflect.get() 替代 obj.key 并不必要,反而增加认知负担。