当然可以!在 JavaScript 中,即使不使用 Array.prototype.flat(),也可以通过多种方式实现数组扁平化(flatten)。下面给你做一个系统总结,包括 递归、迭代、reduce、栈/队列等方法,并附上示例代码。
【JavaScript】不用 flat 扁平化数组的方法
假设我们有一个数组:
const arr = [1, [2, [3, 4], 5], 6];
目标是把它扁平化成:
[1, 2, 3, 4, 5, 6]
1️⃣ 递归法(最常用)
function flatten(arr) {
let result = [];
for (let item of arr) {
if (Array.isArray(item)) {
result = result.concat(flatten(item)); // 递归扁平化
} else {
result.push(item);
}
}
return result;
}
console.log(flatten(arr)); // [1, 2, 3, 4, 5, 6]
特点:
- 简单直观
- 可处理任意深度
- 可能会产生 栈溢出(极深嵌套数组)
2️⃣ reduce + 递归
function flatten(arr) {
return arr.reduce((acc, val) =>
acc.concat(Array.isArray(val) ? flatten(val) : val)
, []);
}
console.log(flatten(arr)); // [1, 2, 3, 4, 5, 6]
优点:
- 函数式写法
- 链式调用可读性好
3️⃣ 栈迭代法(非递归)
如果担心递归栈溢出,可以用 栈迭代:
function flatten(arr) {
const stack = [...arr];
const result = [];
while (stack.length) {
const next = stack.pop();
if (Array.isArray(next)) {
stack.push(...next); // 展开数组
} else {
result.push(next);
}
}
return result.reverse(); // 因为栈是 LIFO
}
console.log(flatten(arr)); // [1, 2, 3, 4, 5, 6]
优点:
- 非递归
- 可处理超深嵌套
4️⃣ 队列迭代法(非递归)
使用队列也可以:
function flatten(arr) {
const queue = [...arr];
const result = [];
while (queue.length) {
const item = queue.shift(); // 队列 FIFO
if (Array.isArray(item)) {
queue.unshift(...item); // 展开到队列前面
} else {
result.push(item);
}
}
return result;
}
console.log(flatten(arr)); // [1, 2, 3, 4, 5, 6]
5️⃣ JSON 方法(只适合纯数字/字符串等值数组)
const flat = JSON.parse('[' + arr.toString() + ']');
console.log(flat); // [1, 2, 3, 4, 5, 6]
⚠️ 注意:
- 不能保留对象或布尔值
- 不能保留
null、undefined、嵌套对象
6️⃣ generator + yield (ES6 高级用法)
function* flattenGen(arr) {
for (let item of arr) {
if (Array.isArray(item)) {
yield* flattenGen(item);
} else {
yield item;
}
}
}
console.log([...flattenGen(arr)]); // [1, 2, 3, 4, 5, 6]
优点:
- 惰性生成
- 支持大数据流,不会一次性占用内存
7️⃣ 总结推荐
| 方法 | 特点 | 适用场景 |
|---|---|---|
| 递归 | 简单易懂 | 小/中等数组 |
| reduce + 递归 | 函数式 | 可链式调用 |
| 栈迭代 | 非递归 | 深度嵌套 |
| 队列迭代 | 非递归 | 深度嵌套 |
| JSON | 简单快速 | 数字/字符串数组 |
| generator | 惰性生成 | 大数据流 |
💡 开发日记小贴士:
- 如果数组深度未知,推荐 栈迭代法 或 generator
- 如果只是小型数组,递归法或 reduce 就够用了
- 尽量避免 JSON 方法用于生产环境(对象/布尔会丢失)
如果你愿意,我可以帮你写一份 JavaScript 高级数组操作技巧合集,包括:
- 扁平化数组多方法对比
- 去重方法总结
- 数组求交集/并集/差集
- 多维数组深拷贝
这套技巧对于 前端面试 + 实战开发 都非常实用。
你想让我直接整理这套高阶数组操作技巧吗?