闭包中func.apply(this, args)与func(...args)的差异及替换可行性
能否用
func(...args)替代func.apply(this, args)?二者差异是什么? 结论:不能无条件直接替代,核心差异集中在this的绑定逻辑,部分边缘场景下参数处理也有区别,具体如下:
1. 最核心的差异:this的指向
func.apply(this, args)会将原函数func的this绑定到当前闭包函数的执行上下文(也就是调用memoize/throttle返回函数时的this)。func(...args)是直接调用函数,此时func的this遵循默认绑定规则:严格模式下为undefined,非严格模式下指向全局对象(浏览器中是window,Node.js中是globalThis)。
举个实际场景的例子:
const user = { name: 'Alice', greet: memoize(function() { return `Hello, ${this.name}`; }) }; // 用apply的写法,greet里的this指向user,输出"Hello, Alice" console.log(user.greet()); // 如果改成func(...args),this指向全局对象(非严格模式)或undefined(严格模式),输出"Hello, undefined"或报错
2. 参数处理的边缘差异
大部分情况下,示例中通过...args得到的是数组,此时func.apply(this, args)和func(...args)的参数传递效果一致。但如果是类数组对象(比如旧版的arguments):
apply可以直接接收类数组作为第二个参数;- 展开语法
...要求参数是可迭代对象,类数组需要先转成数组(比如Array.from(args))才能用展开语法传递。
不过在你给出的memoize和throttle示例中,args是通过剩余参数得到的数组,这部分差异不会体现。
什么时候可以替换?
如果原函数func是不依赖this的纯函数,比如只处理传入的参数、不访问上下文对象,那么用func(...args)完全没问题,结果和apply写法一致。但如果func需要正确的this上下文(比如对象方法、DOM事件处理函数),就必须保留apply(或者用等价的func.call(this, ...args))来绑定正确的this。
内容的提问来源于stack exchange,提问作者deadboyFreak
相关产品推荐
相关产品推荐

