reflect.apply 的核心作用是精确控制函数调用时的 this 值,严格按传入值设定,不自动转换 null/undefined,不包装原始值,不继承默认 this,且与 proxy 的 apply trap 完全兼容。

Reflect.apply 的核心作用,就是让你完全掌控函数调用时的 this 值——不猜测、不推导、不隐式转换,你传什么,函数内部的 this 就是什么。
它不自动修正 this,也不做任何“好意”的转换
传统 fn.call(null) 在非严格模式下会把 null 自动换成 window 或 globalThis;而 Reflect.apply(fn, null, []) 中的 null 就是 null,undefined 就是 undefined。这种“原样传递”看似严苛,实则是可预测性的基础。
- 严格模式下:传
null→ 函数内this === null - 非严格模式下:传
null或undefined→this仍为null/undefined(不会自动升格为全局对象) - 传原始值(如
42、"hello")→this就是那个原始值,不会被包装成对象
必须显式提供 this,不存在“默认继承”
它不看调用位置,也不关心外层作用域。哪怕你在某个对象方法里调用 Reflect.apply,只要第二个参数不是那个对象,this 就不会指向它。
- ✅
Reflect.apply(fn, obj, [1, 2])→fn内部this指向obj - ❌
Reflect.apply(fn, undefined, [1, 2])→this就是undefined(严格模式下),不是外层对象 - ⚠️ 箭头函数无视 this:即使你传了
obj,箭头函数内部this仍由定义时决定,Reflect.apply对它无效
与 Proxy 的 apply trap 天然配合
当你用 Proxy 拦截函数调用时,handler.apply 接收的正是 (target, thisArg, args) 三元组——和 Reflect.apply 的参数顺序、语义完全一致。这意味着:
- 在拦截器中继续执行原逻辑,只需写
return Reflect.apply(target, thisArg, args) - 它能安全调用任何可调用对象(包括被 Proxy 包裹过的函数、无
apply方法的对象) - 避免了
target.apply(thisArg, args)可能因原型被改写或缺失apply而失败
常见兜底写法:安全传入 this
如果你希望 this 至少是个对象(避免 Cannot read property 'x' of undefined),可以主动处理:
-
Reflect.apply(fn, thisArg ?? {}, args)——null或undefined时用空对象兜底 -
Reflect.apply(fn, thisArg || globalThis, args)—— 模拟非严格模式下的默认行为 - 但要注意:这些是业务逻辑判断,不是
Reflect.apply自身的行为










