JavaScript回调函数每次调用都会重新创建吗?GC优化相关疑问
回调函数会被重复创建还是复用?
好问题!这其实得看具体场景,但先给你个明确的结论:你示例里的那个匿名回调函数只会被创建一次,绝对不会给bigArray的每个元素都新建一遍。
我来拆解一下背后的逻辑:
不管是原生JS的
Array.map()还是Lodash的_.map,当你把一个函数作为参数传入时,这个函数在调用map方法之前就已经创建完成了。map内部做的只是在每次迭代时调用这个已经存在的函数实例,而不是每次迭代都重新生成一个新函数。
比如你写的这段代码:const bigArrayClone = _.map(bigArray, function(el){return el;});这里的
function(el){return el;}在_.map执行前就被定义并传入了,_.map拿到的是这个函数的引用,后续所有迭代都是调用同一个函数。容易踩坑的反例是在重复执行的代码块里定义回调,比如循环、频繁触发的事件处理函数里:
// 这种情况会每次循环都创建新的回调函数,增加GC压力 for (let i = 0; i < 10; i++) { const clone = bigArray.map(el => el); }这时候每次循环里的箭头函数都是全新的实例,用完就会变成垃圾等待回收。解决办法也很简单——把回调函数提出来复用:
// 只创建一次,反复复用 const identityFn = el => el; for (let i = 0; i < 10; i++) { const clone = bigArray.map(identityFn); }额外提一句:Lodash本身就内置了一个恒等函数
_.identity,功能就是返回传入的参数,你完全可以直接用它替代自己写的匿名函数,连定义都省了:const bigArrayClone = _.map(bigArray, _.identity);
总结一下:你现在的写法完全没问题,不会产生额外的GC开销。需要注意的是避免在高频执行的代码块内定义回调函数,那样才会导致函数实例反复创建堆积。
内容的提问来源于stack exchange,提问作者Geert-Jan
相关产品推荐
相关产品推荐

