JavaScript 数组方法全面解析

JavaScript 数组方法全面解析

一、数组基础

JavaScript 数组是用于存储多个值的有序集合,具有以下特点:

  • 可以存储任意类型的值
  • 大小可动态调整
  • 具有类型化的方法用于常见操作

创建数组

// 字面量创建 const arr1 = []; const arr2 = [1, 2, 3]; // 构造函数创建 const arr3 = new Array(); const arr4 = new Array(1, 2, 3); const arr5 = new Array(5); // 创建长度为5的空数组

二、会修改原数组的方法

1. push() - 末尾添加元素

const fruits = ['apple', 'banana']; const count = fruits.push('orange'); console.log(fruits); // ['apple', 'banana', 'orange'] console.log(count); // 3 (返回新长度)

2. pop() - 移除末尾元素

const fruits = ['apple', 'banana', 'orange']; const last = fruits.pop(); console.log(fruits); // ['apple', 'banana'] console.log(last); // 'orange' (返回被移除的元素)

3. unshift() - 头部添加元素

const fruits = ['banana', 'orange']; const count = fruits.unshift('apple'); console.log(fruits); // ['apple', 'banana', 'orange'] console.log(count); // 3 (返回新长度)

4. shift() - 移除头部元素

const fruits = ['apple', 'banana', 'orange']; const first = fruits.shift(); console.log(fruits); // ['banana', 'orange'] console.log(first); // 'apple' (返回被移除的元素)

5. splice() - 添加/删除元素

const fruits = ['apple', 'banana', 'orange', 'grape']; // 删除元素: splice(startIndex, deleteCount) const removed = fruits.splice(1, 2); console.log(fruits); // ['apple', 'grape'] console.log(removed); // ['banana', 'orange'] // 添加元素: splice(index, 0, elem1, elem2, ...) fruits.splice(1, 0, 'banana', 'orange'); console.log(fruits); // ['apple', 'banana', 'orange', 'grape'] // 替换元素: splice(index, deleteCount, elem1, elem2, ...) const replaced = fruits.splice(1, 2, 'mango', 'peach'); console.log(fruits); // ['apple', 'mango', 'peach', 'grape'] console.log(replaced); // ['banana', 'orange']

6. reverse() - 反转数组顺序

const nums = [1, 2, 3]; nums.reverse(); console.log(nums); // [3, 2, 1] (返回反转后的数组)

7. sort() - 数组排序

const fruits = ['banana', 'apple', 'orange']; fruits.sort(); console.log(fruits); // ['apple', 'banana', 'orange'] (返回排序后的数组) // 数字排序需要比较函数 const nums = [10, 5, 40, 25]; nums.sort((a, b) => a - b); console.log(nums); // [5, 10, 25, 40]

8. fill() - 填充数组

const arr = [1, 2, 3, 4]; arr.fill(0, 1, 3); // (value, start, end) console.log(arr); // [1, 0, 0, 4] // 填充整个数组 const newArr = new Array(3).fill('x'); console.log(newArr); // ['x', 'x', 'x']

9. copyWithin() - 复制数组元素

const arr = [1, 2, 3, 4, 5]; arr.copyWithin(0, 3, 4); // (target, start, end) console.log(arr); // [4, 2, 3, 4, 5]

三、不会修改原数组的方法

1. concat() - 合并数组

const arr1 = [1, 2]; const arr2 = ['a', 'b']; const arr3 = arr1.concat(arr2, 3, [4, 5]); console.log(arr1); // [1, 2] (原数组不变) console.log(arr3); // [1, 2, 'a', 'b', 3, 4, 5]

2. slice() - 提取子数组

const fruits = ['apple', 'banana', 'orange', 'grape']; const citrus = fruits.slice(1, 3); // (start, end) console.log(fruits); // ['apple', 'banana', 'orange', 'grape'] (原数组不变) console.log(citrus); // ['banana', 'orange']

3. join() - 数组转字符串

const fruits = ['apple', 'banana', 'orange']; const str = fruits.join(' - '); console.log(str); // 'apple - banana - orange' (返回字符串)

4. indexOf() / lastIndexOf() - 查找元素索引

const fruits = ['apple', 'banana', 'orange', 'banana']; console.log(fruits.indexOf('banana')); // 1 console.log(fruits.lastIndexOf('banana')); // 3 console.log(fruits.indexOf('grape')); // -1 (未找到)

5. includes() - 检查是否包含

const fruits = ['apple', 'banana', 'orange']; console.log(fruits.includes('banana')); // true console.log(fruits.includes('grape')); // false

6. find() / findIndex() - 查找元素

const users = [ {id: 1, name: 'John'}, {id: 2, name: 'Jane'}, {id: 3, name: 'Bob'} ]; const user = users.find(u => u.id === 2); console.log(user); // {id: 2, name: 'Jane'} const index = users.findIndex(u => u.name === 'Bob'); console.log(index); // 2

7. filter() - 过滤数组

const nums = [1, 2, 3, 4, 5]; const evens = nums.filter(n => n % 2 === 0); console.log(evens); // [2, 4] (返回新数组)

8. map() - 映射新数组

const nums = [1, 2, 3]; const squared = nums.map(n => n * n); console.log(squared); // [1, 4, 9]

9. reduce() / reduceRight() - 归并数组

const nums = [1, 2, 3, 4]; const sum = nums.reduce((acc, cur) => acc + cur, 0); console.log(sum); // 10 // 计算数组元素出现次数 const fruits = ['apple', 'banana', 'apple', 'orange']; const count = fruits.reduce((acc, fruit) => { acc[fruit] = (acc[fruit] || 0) + 1; return acc; }, {}); console.log(count); // {apple: 2, banana: 1, orange: 1}

10. some() / every() - 测试数组

const nums = [1, 2, 3, 4]; console.log(nums.some(n => n > 3)); // true (至少一个元素满足条件) console.log(nums.every(n => n > 0)); // true (所有元素满足条件)

11. flat() - 数组扁平化

const arr = [1, [2, [3, [4]]]]; console.log(arr.flat()); // [1, 2, [3, [4]]] console.log(arr.flat(2)); // [1, 2, 3, [4]] console.log(arr.flat(Infinity)); // [1, 2, 3, 4]

12. flatMap() - 映射后扁平化

const arr = [1, 2, 3]; const result = arr.flatMap(x => [x, x * 2]); console.log(result); // [1, 2, 2, 4, 3, 6]

四、数组遍历方法

1. forEach() - 遍历数组

const fruits = ['apple', 'banana', 'orange']; fruits.forEach((fruit, index) => { console.log(`${index}: ${fruit}`); }); // 0: apple // 1: banana // 2: orange

2. entries() / keys() / values() - 迭代器方法

const arr = ['a', 'b', 'c']; // 键值对迭代器 for (const [index, element] of arr.entries()) { console.log(index, element); } // 键迭代器 for (const index of arr.keys()) { console.log(index); } // 值迭代器 for (const element of arr.values()) { console.log(element); }

五、其他实用方法

1. Array.from() - 类数组转数组

const arrayLike = {0: 'a', 1: 'b', length: 2}; const arr = Array.from(arrayLike); console.log(arr); // ['a', 'b'] // 从字符串创建 console.log(Array.from('hello')); // ['h', 'e', 'l', 'l', 'o']

2. Array.of() - 创建数组

console.log(Array.of(1, 2, 3)); // [1, 2, 3] console.log(Array.of(3)); // [3] (不同于 new Array(3))

3. isArray() - 检查是否为数组

console.log(Array.isArray([])); // true console.log(Array.isArray({})); // false

六、性能考虑

  1. 修改原数组的方法(push/pop/shift/unshift/splice等)在大型数组上可能性能较差
  2. 创建新数组的方法(map/filter/slice等)通常更安全但会产生内存开销
  3. 遍历方法(forEach/reduce等)比传统的for循环稍慢,但代码更清晰

七、总结图表

方法分类方法名是否修改原数组返回值
修改方法push()✔️新长度
pop()✔️被移除的元素
unshift()✔️新长度
shift()✔️被移除的元素
splice()✔️被删除元素的数组
reverse()✔️反转后的数组
sort()✔️排序后的数组
fill()✔️修改后的数组
copyWithin()✔️修改后的数组
不修改方法concat()新数组
slice()子数组
join()字符串
indexOf()/lastIndexOf()索引或-1
includes()布尔值
find()/findIndex()元素或索引
filter()新数组
map()新数组
reduce()/reduceRight()累积结果
some()/every()布尔值
flat()/flatMap()新数组
遍历方法forEach()undefined
entries()/keys()/values()迭代器

掌握这些数组方法可以让你更高效地处理数据集合,根据是否需要修改原数组和具体需求选择合适的方法。