为什么闭包比普通JavaScript对象占用更多内存?
为什么闭包比普通JavaScript对象占用更多内存?
嘿,这个问题问得挺实在的!咱们先通过实际的Node.js测试代码看看差异,再掰开揉碎聊背后的原因~
先看创建普通对象数组的测试:
const list = Array(1e6).fill(0).map((_, i) => i); const obj_list = list.map(v => ({ v })); console.log(process.memoryUsage()); // { // rss: 130670592, // heapTotal: 86892544, // heapUsed: 54635152, // external: 1019787, // arrayBuffers: 16858 // }
再看创建闭包函数数组的测试:
const list = Array(1e6).fill(0).map((_, i) => i); const fun_list = list.map(v => () => v); console.log(process.memoryUsage()); // { // rss: 189992960, // heapTotal: 152428544, // heapUsed: 117480576, // external: 1019787, // arrayBuffers: 16858 // }
对比两组结果就能发现,闭包数组的堆内存占用直接翻了一倍还多!为啥会有这么大差距?主要是这几个原因:
- 闭包带了个「作用域小背包」:每个闭包函数都会捕获它创建时的外层作用域环境——哪怕你看起来只用到了
v,这个环境对象还是会被完整保留下来,额外占用内存。而普通对象就是个简单的键值对容器,只存你定义的v属性,没这些额外的作用域信息。 - 函数本身就是个复杂对象:JavaScript里的函数是一等公民,本身就包含一堆元数据——比如[[Environment]]内部槽、原型链、函数体代码、参数定义等等。相比之下,普通对象的结构简单得多,没有这些函数特有的额外属性和内部槽位。
- 两者的内存结构天差地别:普通对象本质是个哈希表(或者类似的存储结构),存的是属性名和值的映射;而闭包函数不仅要存函数本身的结构,还要绑定外部作用域的引用,相当于每个闭包都是「函数实体+作用域快照」的组合体,内存开销自然大很多。
简单总结就是:闭包不是单纯存个值,它是带着作用域上下文的函数实体,比普通对象的“体重”重太多啦!
备注:内容来源于stack exchange,提问作者xialvjun
相关产品推荐
相关产品推荐

