数组是 JS 中最常用的数据结构之一,几乎每天都在用。但你真的了解它吗?
今天我们就通过几段代码 + 实际对比,深入聊聊:
✅ 数组如何创建?
✅ 有哪些遍历方式?
✅ 哪种写法更高效?
✅ 为什么说“数组是开箱即用”的好选择?
1️⃣ 数组的创建方式
// 方式一:字面量(最常用)
const arr = [1, 2, 3, 4, 5, 6];
// 方式二:构造函数 + fill(适用于预分配空间)
const arr2 = new Array(10).fill(0);
💡
new Array(10).fill(0)是一种常见初始化技巧,比如创建一个长度为 10 的空数组。
⚠️ 注意事项:
- 如果不知道元素具体值,可以用这种方式提前申请空间。
- 但如果要少了怎么办?JS 支持动态扩容,所以不用担心“空间不够”。
- 要多了?也没关系,JS 会自动处理,不会浪费太多内存。
📌 结论:数组支持动态扩展,比链表更适合大多数场景(尤其是少量数据)。
2️⃣ 如何遍历数组?五种方法对比
✅ 方法一:for...of —— 简洁易读
const arr = [1, 2, 3, 4, 5, 6];
for (let item of arr) {
console.log(item);
}
- ✅ 可读性好
- ✅ 不需要索引
- ✅ ES6 提供的新语法,推荐使用
✅ 方法二:map() —— 遍历 + 加工,返回新数组
const newArr = arr.map(item => item + 1);
console.log(newArr); // [2, 3, 4, 5, 6, 7]
- ✅ 不修改原数组
- ✅ 适合数据转换(如映射、格式化)
- ❌ 不能 break,不适合条件判断
✅ 方法三:forEach() —— 遍历执行函数
arr.forEach((item, index) => {
console.log(item, index);
});
- ✅ 可以拿到索引
- ❌ 不能使用
break或return - ❌ 性能较差(函数入栈出栈开销大)
🔍 小知识:
forEach是基于函数调用的,每次都要创建函数上下文,所以性能不如普通循环。
✅ 方法四:传统 for 循环 —— 性能之王
const len = arr.length; // 先缓存 length,避免重复查询
for (let i = 0; i < len; i++) {
console.log(arr[i]);
}
- ✅ 性能最好(CPU 工作模式契合)
- ✅ 支持
break/continue - ✅ 适合大数据量或性能敏感场景
🚀 为什么快?因为它是“计数循环”,CPU 处理起来非常高效,且只访问一次
length属性。
❌ 方法五:for...in(不推荐用于数组)
// 不要这样写!
for (let key in arr) {
console.log(arr[key]);
}
- ❌ 会遍历所有可枚举属性(包括原型链)
- ❌ 效率低,容易出错
3️⃣ 总结:哪种遍历方式最合适?
| 方法 | 是否推荐 | 优点 | 缺点 |
|---|---|---|---|
for...of | ✅ 推荐 | 代码简洁,可读性强 | 无索引 |
map() | ✅ 推荐 | 返回新数组,函数式编程 | 不能中断 |
forEach() | ⚠️ 慎用 | 可读性好 | 不能 break,性能差 |
for 循环 | ✅ 推荐(性能优先) | 最快,可控性强 | 写法稍复杂 |
for...in | ❌ 不推荐 | 会遍历原型 | 容易出错 |
4️⃣ 数组 vs 链表:谁更优秀?
图片中提到:“少数数据的情况下,数组是更优秀的。”
我们来简单对比一下:
| 特性 | 数组 | 链表 |
|---|---|---|
| 内存 | 连续存储 | 离散存储 |
| 访问速度 | O(1) 快 | O(n) 慢 |
| 插入/删除 | O(n) 慢 | O(1) 快 |
| 动态扩容 | ✅ 自动 | ❌ 手动管理 |
| 开发成本 | 低 | 高 |
📌 结论:
- 日常开发中,数组是首选,因为它简单、高效、开箱即用。
- 链表虽然灵活,但在 JS 中很少手动实现,除非有特殊需求(如实现栈、队列等)。
✅ 最佳实践建议
- 遍历小数组:用
for...of或map() - 遍历大数组:用
for循环(性能最优) - 需要改造数据:用
map() - 只需要打印/处理:用
for...of - 避免使用
forEach和for...in