如何用 Reflect.apply 动态调用函数并以更规范的方式传递上下文的重点在于把前置条件、操作顺序和容易误判的地方分清楚。
Reflect.apply 更规范,因其是ECMAScript明确定义的函数调用抽象操作反射接口,不依赖目标函数是否有call/apply方法,也不自动转换this值,且要求第三参数必须为真数组。
因为 Reflect.apply 是 ECMAScript 明确定义的“函数调用抽象操作”的反射接口,它不依赖于目标函数是否具有 call 或 apply 方法(比如某些 Proxy handler 返回的函数可能没有这些方法),也不受 this 绑定方式干扰。当你需要在元编程、装饰器或安全沙箱中动态调用函数时,Reflect.apply 是更底层、更可预测的选择。
常见错误是把它当成 Function.prototype.apply 的语法糖来用——其实它语义更纯粹:只做「以指定 this 和参数列表执行函数」这一件事,不附带任何额外行为(比如 apply 在非严格模式下会把 null/undefined this 自动转为全局对象)。
Reflect.apply 的第三个参数必须是真数组(Array 实例),不能是类数组(如 arguments、NodeList)。否则会抛出 TypeError: CreateListFromArrayLike called on non-object。
Reflect.apply(fn, ctx, Array.from(arguments)) 或 Reflect.apply(fn, ctx, [...arguments])
Reflect.apply(fn, ctx, arguments)(即使 arguments 看起来像数组)Reflect.apply 对 thisArg 的处理和严格模式下的 call 一致:不会自动转换 null 或 undefined,也不会把原始值包装成对象。这反而是优势——行为可预测。
null 或 undefined → 函数内部 this 就是 null/undefined(严格模式下正常,非严格模式下也保持原样)42、"str")→ 不会隐式装箱,this 就是那个原始值(而 fn.call(42) 会变成 new Number(42))Reflect.apply 的“修复”在 Proxy 的 apply handler 中返回的函数,若再被 Reflect.apply 调用,必须确保该函数自身支持标准调用协议。某些框架生成的“伪函数”(如 React 的 bound 函数、Babel 编译的箭头函数 wrapper)可能缺失 [[Call]] 内部方法,导致 Reflect.apply 报错 TypeError: Function expected。
typeof fn === 'function' 且 fn != null
Proxy 对象本身调用 Reflect.apply,除非你明确实现了它的 apply trapif (typeof target === 'function') {<br> return Reflect.apply(target, thisArg, args);<br>}