JavaScript 数组详解:从入门到精通

106 阅读5分钟

什么是数组?

数组(Array)是 JavaScript 中用于按顺序存储一组数据的数据结构。每个数据称为“元素”,每个元素有一个对应的“索引”(下标),索引从 0 开始。

数组的创建方式

1. 字面量创建(最常用)

// 创建空数组
const emptyArray = [];

// 创建包含初始元素的数组(可混合不同类型)
const numbers = [1, 2, 3, 4, 5];
const mixedTypes = [1, "hello", true, null, { key: "value" }];

2. 构造函数创建

// 创建空数组(不推荐,优先用 [])
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 的数组。
    const arr = new Array(3);
    arr.map(x => 0); // [empty × 3](map 无法处理 empty)

3.Array.of () 方法(ES6+)

// 创建包含指定元素的数组(解决 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

// 从类数组对象(如 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 属性
    表示数组的长度,可以手动修改。
    • 作用:返回数组的长度(元素个数)。
const arr = [1, 2, 3];
arr.length; // 3
arr.length = 5; // 扩展数组:[1, 2, 3, empty × 2]
arr.length = 2; // 截断数组:[1, 2]
  • 稀疏数组
    索引不连续的数组(存在 empty 元素)。
const sparse = [];
sparse[2] = 'c'; // [empty × 2, 'c']
  • 数组可以存放任意类型的数据
    let 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 循环

语法

for (初始化; 条件; 迭代) {
  // 循环体
}

示例

const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]); // 1, 2, 3
}

特点:灵活性高,可控制索引增减(如反向遍历 i--);性能稳定,适合大型数组;但语法冗长,需手动维护索引。

2. for...in 循环

语法

for (const 索引 in 数组) {
  // 循环体
}

示例

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 方法

语法


数组.forEach((元素, 索引, 原数组) => {
  // 处理每个元素
});

示例


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+)

语法


for (const 元素 of 数组) {
  // 循环体
}

示例


const arr = [100, 200, 300];
for (const item of arr) {
  console.log(item); // 100, 200, 300
}

特点:直接遍历元素(非索引);支持 breakcontinue 控制循环;可遍历数组、字符串、MapSet 等可迭代对象,是数组遍历的推荐方式之一。

5. 迭代方法(map/filter/reduce 等)

这类方法虽主要用于数据处理,但本质是遍历数组并返回新结果:

  • map:遍历并返回处理后的新数组

    
    const arr = [1, 2, 3];
    const doubled = arr.map(item => item * 2); // [2, 4, 6]
    
  • filter:遍历并返回符合条件的元素组成的新数组

    
    const evenNumbers = arr.filter(item => item % 2 === 0); // [2]
    
  • reduce:遍历并累积计算结果

    
    const sum = arr.reduce((total, item) => total + item, 0); // 6
    

特点:不修改原数组,返回新数组或计算结果;适合数据转换、过滤、聚合等场景。

6. some/every 方法

用于判断数组元素是否满足条件(遍历可中断):

  • some:只要有一个元素满足条件就返回 true

    
    const hasEven = arr.some(item => item % 2 === 0); // true
    
  • every:所有元素满足条件才返回 true

    
    const allPositive = arr.every(item => item > 0); // true
    

特点:找到符合条件的元素后会立即停止遍历,效率较高。

小结

  1. 创建:字面量 [] 最直观;new Array(n) 会生成稀疏数组;Array.of/Array.from/... 拓展了灵活初始化与转换方式。
  2. 操作push/pop/unshift/shift/splice 负责增删改;indexOf/includes/find 负责查;map/filter/reduce 负责批量转换与聚合。
  3. 遍历
    • 精准控制用 for
    • 简洁元素用 for...of
    • 链式处理用 map/filter/reduce
    • 注意 for...in、稀疏数组和 empty 元素的坑。

一句话速记

数组的本质是“有序列表”,掌握创建、遍历、处理三件套,就掌握了 80% 的数组实战。