JavaScript 数组精讲:创建与遍历全解析

JavaScript 数组详解:从定义、创建到遍历,全面掌握数组的使用

JavaScript 中的数组(Array)是一种特殊的对象类型 ,用于存储多个值 ,并支持动态扩容、快速访问、遍历和操作。它是 JavaScript 中最基础、最常用的数据结构之一,掌握数组的使用对于前端开发至关重要。


一、什么是数组?

数组是一个有序的元素集合 ,每个元素都有一个索引(从 0 开始),可以通过索引快速访问数组中的元素。

数组的特性:

  • 可遍历:可以使用多种方式遍历数组中的元素
  • 动态扩容:可以随时添加或删除元素,数组大小自动调整
  • 支持多种数据类型:数组中的元素可以是任意类型
  • 具备对象特性:可以像对象一样设置键值对(但不推荐)

二、数组的创建方法

JavaScript 提供了多种方式来创建数组,每种方式都有其适用场景。

1. 使用字面量语法创建数组

javascript 复制代码
const arr = [1, 2, 3]; // 创建一个包含3个元素的数组
  • ✅ 语法简洁
  • ✅ 可读性强
  • ❌ 不适用于动态创建固定长度的数组

2. 使用构造函数 new Array()

javascript 复制代码
const arr1 = new Array(5); // 创建一个长度为5的空数组([empty × 5])
const arr2 = new Array(1, 2, 3); // 创建数组 [1, 2, 3]
⚠️ 注意事项:
  • new Array(5) 并不会创建一个包含 5 个 undefined 的数组,而是创建一个长度为 5 的"空数组",在 for...in 遍历时不会触发任何迭代。
  • 如果你想创建一个可遍历的数组,可以使用:
javascript 复制代码
const arr = new Array(5).fill(undefined); // [undefined, undefined, undefined, undefined, undefined]

empty不被当作属性,而undefined会被当做属性遍历


3. 使用静态方法创建数组

Array.of()
javascript 复制代码
console.log(Array.of(1, 'a', 3)); // [1, "a", 3]
  • 用途:将一组值转换为数组
  • 特点:参数会直接作为数组元素
Array.from()
javascript 复制代码
console.log(Array.from(new Array(26), (val, index) => String.fromCharCode(65 + index)));
// ['A', 'B', 'C', ..., 'Z']
  • 用途:将类数组或可迭代对象转换为数组
  • 支持映射函数 :可以配合 map 函数进行转换

三、数组的高级特性

1. 动态扩容

JavaScript 的数组是动态的,你可以随时添加或删除元素:

javascript 复制代码
const arr = [1, 2];
arr[5] = 6; // 数组自动扩容,中间位置为 undefined
console.log(arr); // [1, 2, undefined, undefined, undefined, 6]

2. 支持 Hash 特性

JavaScript 数组本质上是对象,因此可以像对象一样设置键值:

javascript 复制代码
const arr = [1, 2, 3];
arr['name'] = '数组'; // 合法,但不推荐

但要注意:这些自定义属性不会被 for...ofmap 等数组方法处理。


四、数组的遍历方法详解

遍历数组是 JavaScript 开发中最常见的操作之一。不同的遍历方式适用于不同的场景。


1. forwhile 循环(基础遍历)

for 循环:
javascript 复制代码
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}
while 循环:
javascript 复制代码
let i = 0;
while (i < arr.length) {
    console.log(arr[i]);
    i++;
}
  • ✅ 性能好
  • ✅ 可中断(break
  • ❌ 可读性较差
  • ✅ 适用于需要索引的场景

2. for...in 遍历(慎用)

javascript 复制代码
for (const key in arr) {
    console.log(key, arr[key]);
}
  • ❌ 不推荐用于数组,因为会遍历原型链上的属性
  • ✅ 适用于对象遍历

3. for...of 遍历(推荐)

javascript 复制代码
for (const item of arr) {
    console.log(item);
}
  • ✅ 可读性好
  • ✅ 可以结合 entries() 获取索引和值
  • ✅ 推荐用于大多数数组遍历场景
获取索引和值:
javascript 复制代码
for (const [index, value] of arr.entries()) {
    console.log(index, value);
}
.entries() 方法说明:
  • arr.entries() 返回一个迭代器(Array Iterator
  • 每次迭代返回 [index, value] 的键值对
  • 配合解构赋值 [index, value] 非常方便

4. forEach() 遍历

javascript 复制代码
arr.forEach((item) => {
    console.log(item);
});
  • ✅ 可读性好
  • ❌ 不能中断(不能 breakreturn
  • ✅ 适用于"对每个元素执行操作"的场景
forEach 的坑:
  • 不能提前中断 :即使你在回调中使用 return,也只是跳过当前循环,不能停止整个遍历
  • 不返回值:只用于执行副作用,不能用于筛选或映射
javascript 复制代码
names.forEach(name => {
    if (name === '张三') {
        console.log('找到了');
        return; // ❌ 只跳过当前循环,不能 break
    }
    console.log('继续找...');
});

5. 高阶函数遍历(map、filter、find、reduce 等)

这些方法不仅用于遍历数组,还能进行转换、筛选、查找等操作。

方法 用途 是否可中断 可读性 返回值
map 映射新数组 新数组
filter 筛选符合条件的元素 新数组
find 找到第一个符合条件的元素 元素或 undefined
some 判断是否有元素符合条件 truefalse
every 判断是否所有元素都符合条件 truefalse
reduce 累计计算 累计结果

6. reduce 方法详解

reduce 是数组中最强大的方法之一,用于将数组中的所有元素"归约"为一个值,比如求和、统计、合并等。

语法:
javascript 复制代码
array.reduce((accumulator, currentValue) => {
  // 返回新的 accumulator
}, initialValue);
示例:求和
javascript 复制代码
const sum = [1, 2, 3, 4, 5, 6].reduce((prev, curr) => prev + curr, 0);
console.log(sum); // 21
示例:统计出现次数
javascript 复制代码
const names = ['张三', '李四', '张三', '王五'];
const count = names.reduce((acc, name) => {
  acc[name] = (acc[name] || 0) + 1;
  return acc;
}, {});
console.log(count); // { 张三: 2, 李四: 1, 王五: 1 }

五、总结对比

方法 是否可中断 可读性 用途
for 基础遍历
while 基础遍历
forEach 对每个元素执行操作
map 映射新数组
filter 筛选符合条件的元素
find 找到第一个符合条件的元素
some 判断是否至少有一个元素符合条件
every 判断是否所有元素都符合条件
reduce 累计计算
for...of 推荐的数组遍历方式
for...in 适用于对象,慎用于数组

六、使用建议

  • 优先使用 for...of :可读性好,支持 break,适用于大多数数组遍历场景
  • 需要索引时使用 entries():可以同时获取索引和值
  • 使用 mapfilterreduce 等高阶函数:使代码更简洁、函数式
  • 避免滥用 for...in:容易遍历到原型链上的属性,不推荐用于数组
  • 不要在数组中滥用对象特性:如设置非数字键值,避免混淆数据结构
相关推荐
拾光拾趣录几秒前
requestIdleCallback:让你的网页如丝般顺滑
前端·性能优化
前端 贾公子3 分钟前
vue-cli 模式下安装 uni-ui
前端·javascript·windows
拾光拾趣录16 分钟前
链表合并:双指针与递归
前端·javascript·算法
@大迁世界21 分钟前
前端:优秀架构的坟墓
前端·架构
拼图20924 分钟前
element-plus——图标推荐
javascript·vue.js·elementui
期待のcode32 分钟前
图片上传实现
java·前端·javascript·数据库·servlet·交互
koooo~1 小时前
JavaScript中的Window对象
开发语言·javascript·ecmascript
hbrown1 小时前
Flask+LayUI开发手记(十一):选项集合的数据库扩展类
前端·数据库·python·layui
猫头虎1 小时前
什么是 npm、Yarn、pnpm? 有什么区别? 分别适应什么场景?
前端·python·scrapy·arcgis·npm·beautifulsoup·pip
迷曳2 小时前
27、鸿蒙Harmony Next开发:ArkTS并发(Promise和async/await和多线程并发TaskPool和Worker的使用)
前端·华为·多线程·harmonyos