Reflect.apply 是 ES6 提供的静态反射方法,用于以指定 this 值和参数数组调用函数,功能等价于 Function.prototype.apply 但语义更清晰、安全性更高,常用于 Proxy 拦截和元编程场景。

Reflect.apply 是 ES6 提供的静态方法,用于以指定的 this 值和参数列表调用目标函数,功能等价于 Function.prototype.apply,但语法更语义化、更安全(不会因目标非函数而抛出类型错误,而是返回 false 或直接报错,取决于使用场景)。
基本用法:替代 Function.prototype.apply
它接收三个参数:target(要调用的函数)、thisArg(函数内部的 this 指向)、argsArray(实参数组或类数组对象)。
- 与
func.apply(thisArg, args)行为一致,但更明确表达“反射式调用”意图 - 如果
target不是函数,会抛出TypeError(这点和apply相同) - 适合在 Proxy、高阶函数或需要显式控制调用上下文的场景中使用
示例:
const sum = (a, b) => a + b;const result = Reflect.apply(sum, null, [2, 3]); // 返回 5
console.log(result); // 5
配合 Proxy 实现调用拦截
在 Proxy 的 apply 捕获器中,常配合 Reflect.apply 实现默认行为转发,避免硬编码 target.apply(...)。
- 保持代码可维护性:修改目标函数签名时,无需同步改拦截逻辑
- 符合最小权限原则:只做必要转发,不擅自修改参数或 this
- 便于添加日志、校验、缓存等横切逻辑
示例:
const handler = {apply(target, thisArg, argumentsList) {
console.log('函数被调用,参数:', argumentsList);
return Reflect.apply(target, thisArg, argumentsList);
}
};
const loggedSum = new Proxy(sum, handler);
loggedSum(4, 6); // 输出日志并返回 10
与普通 apply 的关键区别
虽然功能相似,但设计定位不同:
-
Reflect.apply属于反射 API,强调“元操作”的可预测性和一致性,是未来面向元编程的标准方式 - 它不挂载在实例上,始终是静态方法调用,避免了原型链污染风险
- 在严格模式下行为更统一,且与
Reflect.construct、Reflect.get等形成语义闭环 - 不能像
func.apply那样被重写或覆盖(它是不可配置、不可枚举、不可写的)
实际使用建议
- 新项目中优先使用
Reflect.apply替代func.apply,尤其在涉及 Proxy 或需显式反射语义的场景 - 注意参数必须是数组或类数组;传入字符串、对象等会触发隐式转换,可能引发意外结果
- 若需兼容老旧环境(如 IE),需搭配 Babel 转译或手动 polyfill
- 不要用它替代简单的直接调用(如
fn(a, b)),除非确实需要动态绑定 this 或参数数组

















