高频数组字面量创建指循环体内每次迭代都新建数组,如const arr = []或[x, y],导致重复内存分配、gc压力增大及引擎优化受阻。

数组字面量在循环中频繁创建,表面看只是 [] 或 [1, 'a', obj] 这样几行代码,但实际可能引发隐性性能问题——尤其在高频迭代(如渲染列表、数据转换、事件处理)场景下。识别这类开销,关键不是“看有没有写 []”,而是判断它是否在每次迭代中**重复分配内存、触发 GC、阻碍优化**。
看是否在循环体内直接 new 或字面量初始化
这是最直观的信号。只要循环体内部出现 let arr = []、const list = [x, y]、return [...old] 等即时创建行为,就属于高频创建。
- 典型例子:遍历用户列表,为每个用户生成一个临时配置数组
// ❌ 问题代码:每次迭代都新建数组,产生 N 次内存分配
users.forEach(user => {<br> const config = ['user', user.id, user.role]; // 每次都 new 一个新数组<br> sendConfig(config);<br>});
- 即使数组内容简单,V8 等引擎仍需为其分配堆内存、设置长度、填充元素;若循环上万次,会显著增加 GC 压力
- 注意:
[...arr]、Array.from(arr)、arr.slice()在循环内使用,也等价于高频创建
看是否用于中间计算且未复用
当数组仅作为“一次性容器”参与计算(如过滤、映射、拼接),又不被缓存或复用,就容易形成冗余开销。
- 例如:在 for 循环中反复
push()到一个新数组,但该数组只在本次迭代末尾被消费一次,之后即被丢弃 - 再如:函数内每次调用都返回新数组(
getTags() { return ['tag1', 'tag2']; }),而该函数被放在循环里调用 - 这类模式常出现在工具函数封装不当、缺乏参数化设计的代码中
借助开发者工具定位真实开销
不能单靠肉眼判断,要用运行时数据验证:
- 在 Chrome DevTools 的 Performance 面板 录制一段含该循环的操作,关注 “Memory Allocation” 轨迹:若出现密集的小块堆分配(尤其是
Array类型),且与循环次数强相关,就是证据 - 打开 Memory 面板 → Allocation instrumentation on timeline,勾选 “Record heap allocations”,执行后查看哪些函数频繁分配 Array 实例
- 对比优化前后:将数组提取到循环外或改用复用策略后,观察 Total time 和 GC pause time 是否明显下降
注意跨上下文的隐蔽创建
有些创建行为不易察觉,但同样高频:
-
JSON.parse('[]')或JSON.stringify([])在循环中调用——本质是解析/序列化新对象,开销远高于字面量 - 使用
map()、filter()等高阶函数时,它们内部必然返回新数组;若嵌套在另一层循环中(如双重 map),就会指数级放大创建次数 - 模板字符串中隐式调用
Array.prototype.toString()(如`${[1,2]}`),虽不显式写[],但每次都会构造并销毁临时数组










