数组字面量初始化本身不产生深度遍历开销,仅分配一层引用;深度遍历开销源于开发者主动的递归或循环逻辑,如JSON.stringify、structuredClone、flat(Infinity)等会隐含全量递归处理。

字面量初始化只分配一层引用
用 [] 创建数组时,JS 引擎只在堆内存中分配连续空间存值或引用,不递归展开嵌套内容:
- 原始值(
number、string、boolean)直接存储 - 对象、数组、函数等复杂类型只存引用地址,不拷贝也不遍历
- 例如:
const arr = [1, [2, 3], {x: 4}]—— 外层数组长度为 3,内部两个嵌套项仍是独立对象,未被“展开”
深度遍历开销来自递归或循环逻辑
当你手动写代码去访问每一层嵌套时,开销才实际发生。常见方式及特点:
- 递归遍历:每次调用栈帧增加,深层嵌套可能触发栈溢出(如 >10000 层)
- 栈模拟迭代(用数组模拟调用栈):避免栈溢出,但需额外内存管理
- JSON.stringify + 正则/字符串解析:看似简单,但序列化+反解析成本高,且无法处理函数、undefined、循环引用
- for / while 配合队列/栈:控制力强、性能可控,推荐用于已知深度或需中断的场景
哪些操作会意外触发深度行为?
有些 API 看似“只是读”,实则隐含深度处理:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
JSON.stringify(arr):会递归序列化所有可枚举属性,遇到函数、Symbol、undefined 会跳过,循环引用报错 -
structuredClone(arr)(现代环境):深克隆,完整遍历并复制所有层级,开销显著 -
arr.flat(Infinity):强制展平所有嵌套,时间复杂度与总元素数和嵌套深度正相关 -
console.log(arr):浏览器控制台展开时视觉上“深度显示”,但实际只惰性加载,不立即遍历全部
优化建议:按需遍历,避免无谓递归
多数业务不需要真正“全深度遍历”。更高效的做法是:
立即学习“Java免费学习笔记(深入)”;
- 明确目标字段路径,用
arr[0]?.children?.[1]?.value等可选链精准访问 - 对树形结构(如菜单、DOM-like 数据),用 BFS/DFS 显式控制遍历范围和终止条件
- 若仅需检测是否存在某类值(如找第一个
null),找到即return,不继续深入无关分支 - 避免在渲染层(如 React)中无节制
JSON.stringify比较 props —— 改用浅比较或自定义 key

















