什么是数组?
数组(Array)是 JavaScript 中用于按顺序存储一组数据的数据结构。每个数据称为"元素",每个元素有一个对应的"索引"(下标),索引从 0 开始。
数组的创建方式
1. 字面量创建(最常用)
js
// 创建空数组
const emptyArray = [];
// 创建包含初始元素的数组(可混合不同类型)
const numbers = [1, 2, 3, 4, 5];
const mixedTypes = [1, "hello", true, null, { key: "value" }];
2. 构造函数创建
js
// 创建空数组(不推荐,优先用 [])
const arr1 = new Array(); // 等价于 []
// 创建指定长度的空数组(元素为 empty,无法直接遍历)
const arr2 = new Array(5); // [empty × 5]
// 创建包含初始元素的数组(多个参数时)
const arr3 = new Array(1, 2, 3); // [1, 2, 3]
const arr4 = Array(4, 5, 6); // 无需 new,效果相同
注意陷阱:
- 单个数值参数 :
new Array(3)
创建长度为 3 的空数组,而非包含元素3
的数组。
javascript
const arr = new Array(3);
arr.map(x => 0); // [empty × 3](map 无法处理 empty)
3.Array.of () 方法(ES6+)
js
// 创建包含指定元素的数组(解决 Array() 的歧义)
const arr1 = Array.of(5); // [5](单个参数不再表示长度)
const arr2 = Array.of(1, 2, 3); // [1, 2, 3]
- 无论参数数量,均将参数作为数组元素。
- 对比
Array(5)
(创建长度为 5 的空数组),Array.of(5)
明确创建包含元素5
的数组。
4. Array.from
js
// 从类数组对象(如 arguments、DOM 节点列表)创建数组
const argsToArray = (a, b, c) => Array.from(arguments);
argsToArray(1, 2, 3); // [1, 2, 3]
// 从可迭代对象(如字符串、Set、Map)创建数组
const arr1 = Array.from("hello"); // ['h', 'e', 'l', 'l', 'o']
const arr2 = Array.from(new Set([1, 2, 2, 3])); // [1, 2, 3]
// 带映射函数:初始化数组并处理元素
const arr3 = Array.from({ length: 3 }, (_, i) => i * 2); // [0, 2, 4]
数组的基本属性和特性
- length 属性
表示数组的长度,可以手动修改。- 作用:返回数组的长度(元素个数)。
js
const arr = [1, 2, 3];
arr.length; // 3
arr.length = 5; // 扩展数组:[1, 2, 3, empty × 2]
arr.length = 2; // 截断数组:[1, 2]
- 稀疏数组
索引不连续的数组(存在empty
元素)。
js
const sparse = [];
sparse[2] = 'c'; // [empty × 2, 'c']
-
数组可以存放任意类型的数据
jslet arr = [1, 'a', true, null, undefined, {x:1}, [2,3]];
数组的常用方法
1. 增删改查
方法 | 作用 | 示例 |
---|---|---|
push | 尾部添加元素 | arr.push(4) |
pop | 尾部删除元素 | arr.pop() |
unshift | 头部添加元素 | arr.unshift(0) |
shift | 头部删除元素 | arr.shift() |
splice | 任意位置增删改 | arr.splice(1, 2, 'a', 'b') |
slice | 截取子数组(不改变原数组) | arr.slice(1, 3) |
2. 查找
方法 | 作用 | 示例 |
---|---|---|
indexOf | 查找元素索引 | arr.indexOf(2) |
lastIndexOf | 从后往前查找索引 | arr.lastIndexOf(2) |
includes | 是否包含某元素 | arr.includes(2) |
find | 查找第一个符合条件的元素 | arr.find(x => x > 2) |
findIndex | 查找第一个符合条件的索引 | arr.findIndex(x => x > 2) |
3. 遍历与转换
方法 | 作用 | 示例 |
---|---|---|
forEach | 遍历数组 | arr.forEach(x => console.log(x)) |
map | 返回新数组 | arr.map(x => x * 2) |
filter | 过滤,返回新数组 | arr.filter(x => x > 2) |
reduce | 累加/汇总 | arr.reduce((a, b) => a + b) |
some | 是否有元素满足条件 | arr.some(x => x > 2) |
every | 是否所有元素都满足条件 | arr.every(x => x > 2) |
4. 其他常用方法
方法 | 作用 | 示例 |
---|---|---|
join | 拼接为字符串 | arr.join('-') |
concat | 合并数组 | arr.concat([4,5]) |
reverse | 反转数组 | arr.reverse() |
sort | 排序 | arr.sort((a, b) => a - b) |
fill | 填充 | arr.fill(0, 1, 3) |
flat | 扁平化 | arr.flat(2) |
at | 支持负索引 | arr.at(-1) |
数组的遍历方式
JavaScript 中的数组遍历方式多样,各有适用场景。
1. 传统 for
循环
语法:
javascript
for (初始化; 条件; 迭代) {
// 循环体
}
示例:
javascript
const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]); // 1, 2, 3
}
特点 :灵活性高,可控制索引增减(如反向遍历 i--
);性能稳定,适合大型数组;但语法冗长,需手动维护索引。
2. for...in
循环
语法:
javascript
for (const 索引 in 数组) {
// 循环体
}
示例:
javascript
const arr = ['a', 'b', 'c'];
for (const index in arr) {
console.log(index, arr[index]); // '0' 'a', '1' 'b', '2' 'c'
}
特点 :遍历的 index
为字符串类型;会遍历数组原型链上的可枚举属性(如添加到 Array.prototype
的方法),因此不推荐用于数组遍历。
3. forEach
方法
语法:
javascript
数组.forEach((元素, 索引, 原数组) => {
// 处理每个元素
});
示例:
javascript
const arr = [10, 20, 30];
arr.forEach((item, index) => {
console.log(item, index); // 10 0, 20 1, 30 2
});
特点 :内置方法,无需手动维护索引;无法中断循环 (不能用 break
或 return
跳出,除非抛出异常);会跳过稀疏数组中的 empty
元素。
4. for...of
循环(ES6+)
语法:
javascript
for (const 元素 of 数组) {
// 循环体
}
示例:
javascript
const arr = [100, 200, 300];
for (const item of arr) {
console.log(item); // 100, 200, 300
}
特点 :直接遍历元素(非索引);支持 break
、continue
控制循环;可遍历数组、字符串、Map
、Set
等可迭代对象,是数组遍历的推荐方式之一。
5. 迭代方法(map
/filter
/reduce
等)
这类方法虽主要用于数据处理,但本质是遍历数组并返回新结果:
-
map
:遍历并返回处理后的新数组javascriptconst arr = [1, 2, 3]; const doubled = arr.map(item => item * 2); // [2, 4, 6]
-
filter
:遍历并返回符合条件的元素组成的新数组javascriptconst evenNumbers = arr.filter(item => item % 2 === 0); // [2]
-
reduce
:遍历并累积计算结果javascriptconst sum = arr.reduce((total, item) => total + item, 0); // 6
特点:不修改原数组,返回新数组或计算结果;适合数据转换、过滤、聚合等场景。
6. some
/every
方法
用于判断数组元素是否满足条件(遍历可中断):
-
some
:只要有一个元素满足条件就返回true
javascriptconst hasEven = arr.some(item => item % 2 === 0); // true
-
every
:所有元素满足条件才返回true
javascriptconst allPositive = arr.every(item => item > 0); // true
特点:找到符合条件的元素后会立即停止遍历,效率较高。
小结
- 创建 :字面量
[]
最直观;new Array(n)
会生成稀疏数组;Array.of
/Array.from
/...
拓展了灵活初始化与转换方式。 - 操作 :
push/pop/unshift/shift/splice
负责增删改;indexOf/includes/find
负责查;map/filter/reduce
负责批量转换与聚合。 - 遍历 :
• 精准控制用for
• 简洁元素用for...of
• 链式处理用map/filter/reduce
• 注意for...in
、稀疏数组和empty
元素的坑。
一句话速记
数组的本质是"有序列表",掌握创建、遍历、处理三件套,就掌握了 80% 的数组实战。