递归遍历多维数组的核心是:遇数组则递归调用,遇非数组元素则处理;可用尾递归优化或栈模拟避免栈溢出,递归简洁但深度大时建议用迭代。

用递归遍历多维嵌套数组,核心是:遇到数组就继续调用自身,遇到非数组元素就处理它。
基础递归结构
判断当前项是否为数组,是则递归调用;否则直接收集或操作该值:
function flatten(arr) {
const result = [];
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
result.push(...flatten(arr[i])); // 展开子数组结果
} else {
result.push(arr[i]);
}
}
return result;
}
// 示例
console.log(flatten([1, [2, [3, 4]], 5])); // [1, 2, 3, 4, 5]
支持任意嵌套类型的通用遍历
如果数组中可能混入对象、null、undefined 等,可扩展判断逻辑:
function traverse(arr, callback) {
for (let item of arr) {
if (Array.isArray(item)) {
traverse(item, callback); // 递归进入子数组
} else {
callback(item); // 对每个叶子节点执行回调
}
}
}
// 使用示例:打印所有非数组元素
traverse([1, [2, [3, null]], { a: 4 }], console.log);
// 输出:1, 2, 3, null, { a: 4 }
带层级信息的深度遍历
若需知道每个元素所在深度(比如用于树形展示),可传入当前层级参数:
function traverseWithDepth(arr, depth = 0, callback) {
for (let item of arr) {
if (Array.isArray(item)) {
traverseWithDepth(item, depth + 1, callback);
} else {
callback(item, depth);
}
}
}
// 示例:缩进打印
traverseWithDepth([1, [2, [3]], 4], (val, d) => {
console.log(' '.repeat(d) + val);
});
// 输出:
// 1
// 2
// 3
// 4
避免栈溢出的尾递归优化(有限支持)
纯尾递归在 JS 中默认不被优化,但可用循环模拟递归调用栈:
function flattenIterative(arr) {
const result = [];
const stack = [...arr]; // 初始化栈
while (stack.length > 0) {
const item = stack.pop();
if (Array.isArray(item)) {
stack.push(...item); // 子数组展开后压入栈顶
} else {
result.push(item);
}
}
return result.reverse(); // 因为用 pop,顺序反了,需反转
}
递归写法简洁直观,适合大多数嵌套不深的场景;若数据极深或需严格控制性能,建议改用栈模拟方式。


















