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...of、map 等数组方法处理。


四、数组的遍历方法详解

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


1. for 和 while 循环(基础遍历)

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

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

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

方法 用途 是否可中断 可读性 返回值
map 映射新数组 ❌ ✅ 新数组
filter 筛选符合条件的元素 ❌ ✅ 新数组
find 找到第一个符合条件的元素 ✅ ✅ 元素或 undefined
some 判断是否有元素符合条件 ✅ ✅ true 或 false
every 判断是否所有元素都符合条件 ✅ ✅ true 或 false
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():可以同时获取索引和值
  • 使用 map、filter、reduce 等高阶函数:使代码更简洁、函数式
  • 避免滥用 for...in:容易遍历到原型链上的属性,不推荐用于数组
  • 不要在数组中滥用对象特性:如设置非数字键值,避免混淆数据结构
相关推荐
乘风gg6 分钟前
Spec Kit vs OpenSpec vs Superpowers:三大 AI Coding 框架深度对比
前端·ai编程·claude
w2sfot23 分钟前
AI时代,JS加密还有效吗?
开发语言·前端·javascript
风骏时光牛马27 分钟前
AI服务线上接口异常导致响应中断
前端
haluhalu.37 分钟前
Agent = LLM + 上下文 + 工具(含观察 / 动作空间、ReAct 循环)
前端·javascript·人工智能·python·react.js·机器学习·个人开发
子兮曰6 小时前
把 649 种文件格式塞进一个网页里:一个「文件不出浏览器」的预览器
前端·javascript·后端
paopaokaka_luck9 小时前
基于springboot+vue的智慧家政管理系统(AI问答、 WebSocket实时沟通、ECharts运营分析、订单规则与服务追踪)
java·javascript·spring boot·数据分析·echarts·mybatis
sm_926787059 小时前
RFID 标签打印的技术实现要点与二次开发实践
java·大数据·前端·c++·编辑器
IMPYLH9 小时前
HTML 的 <video> 元素
前端·html
溪语流沙10 小时前
【每天一个CSS | Day19】流光文字与一笔写成的手写签名
前端·javascript·css
逐光者93310 小时前
STM32——SPI 屏 · Flash · 高速
java·前端·stm32