那些年我们踩过的数组坑
坑1:Array.prototype.sort 的默认行为
你以为 [1, 5, 10].sort() 会得到 [1, 5, 10]?试试看:
[1, 5, 10].sort(); // 实际输出 [1, 10, 5
[1, 5, 10].sort((a, b) => a - b);
坑2:delete 操作符的 "空洞"
const arr = ['a', 'b', 'c'];
delete arr[1];
console.log(arr.length); // 仍然是 3!
console.log(arr); // ['a', 空, 'c']
delete 会移除索引值但不更新数组长度,导致后续的 map/forEach 等遍历方法仍会访问到空位。应该用 splice:
arr.splice(1, 1); // 正确姿势
坑3:reduce 的初始值陷阱
[{x:1}, {x:2}].reduce((sum, item) => sum.x + item.x); // 报错!
第一次迭代时 sum 是数组第一项 {x:1},第二次试图访问 sum.x 时 sum 已经是前一次的运算结果(数字)。正确的写法:
[{x:1}, {x:2}].reduce((sum, item) => sum + item.x, 0); // 记得初始值
避坑清单:数组操作黄金法则
链式调用别超过 3 步:超过就改用 for 循环或 reduce
超大数组用 for 而不是 forEach:for 循环在 V8 中有特殊优化
检查排序回调函数:永远不要依赖默认排序
慎用 delete 操作符:数组删元素优先选 splice
reduce 必须带初始值:除非你明确知道自己在做什么
回到开头的案例——最终的解决方案是改用流式处理(Node.js Stream)分批处理日志,将内存控制在 100MB 以内。JavaScript 的数组方法像瑞士军刀,但刀刃越锋利,割伤自己时就越疼。
你在项目中有没有遇到过类似的数组陷阱?欢迎分享你的 "血泪史"。