在 JavaScript 中,数组的处理函数(也称为数组方法)非常丰富和强大,它们是处理列表数据的核心。下面我将它们分为几大类,并详细介绍每个方法的作用、参数和返回值。
一、 会改变原数组的方法 (Mutator Methods)
这些方法会直接修改原始数组。
1. push()
- 作用:向数组的末尾添加一个或多个元素。
- 参数:要添加的元素(任意数量)。
-
返回值:数组新的
length
。 -
示例:
let arr = [1, 2]; let newLength = arr.push(3, 4); console.log(arr); // [1, 2, 3, 4] console.log(newLength); // 4
2. pop()
- 作用:删除并返回数组的最后一个元素。
- 参数:无。
-
返回值:被删除的元素。如果数组为空则返回
undefined
。 -
示例:
let arr = [1, 2, 3]; let lastElement = arr.pop(); console.log(arr); // [1, 2] console.log(lastElement); // 3
3. unshift()
- 作用:向数组的开头添加一个或多个元素。
- 参数:要添加的元素(任意数量)。
-
返回值:数组新的
length
。 -
示例:
let arr = [3, 4]; let newLength = arr.unshift(1, 2); console.log(arr); // [1, 2, 3, 4] console.log(newLength); // 4
4. shift()
- 作用:删除并返回数组的第一个元素。
- 参数:无。
-
返回值:被删除的元素。如果数组为空则返回
undefined
。 -
示例:
let arr = [1, 2, 3]; let firstElement = arr.shift(); console.log(arr); // [2, 3] console.log(firstElement); // 1
5. splice()
- 作用:功能强大的方法,用于删除、替换或添加数组中的元素。
-
参数:
-
start
:开始修改的索引位置。 -
deleteCount
(可选):要移除的元素个数。如果为 0 或负数,则不删除元素。 -
item1, item2, ...
(可选):要添加到数组的元素,从start
位置开始。
-
- 返回值:由被删除的元素组成的数组。如果没有删除元素,则返回空数组。
-
示例:
let arr = ['a', 'b', 'c', 'd']; // 删除:从索引1开始,删除2个元素 let removed = arr.splice(1, 2); console.log(arr); // ['a', 'd'] console.log(removed); // ['b', 'c'] // 添加:从索引1开始,删除0个元素,添加'x', 'y' arr.splice(1, 0, 'x', 'y'); console.log(arr); // ['a', 'x', 'y', 'd'] // 替换:从索引1开始,删除2个元素,添加'z' arr.splice(1, 2, 'z'); console.log(arr); // ['a', 'z', 'd']
6. reverse()
- 作用:将数组中元素的顺序反转。
- 参数:无。
- 返回值:反转后的原数组(原数组已被改变)。
-
示例:
let arr = [1, 2, 3]; arr.reverse(); console.log(arr); // [3, 2, 1]
7. sort()
- 作用:对数组的元素进行排序,默认是将元素转换为字符串,然后比较它们的 UTF-16 码元序列。
-
参数(可选):一个比较函数,用于定义排序顺序。
- 比较函数接收两个参数
a
和b
。 - 如果返回值 < 0,则
a
排在b
前面。 - 如果返回值 > 0,则
b
排在a
前面。 - 如果返回值 == 0,则
a
和b
的相对位置不变。
- 比较函数接收两个参数
- 返回值:排序后的原数组(原数组已被改变)。
-
示例:
let arr = [10, 2, 1]; arr.sort(); // 默认排序,按字符串比较 console.log(arr); // [1, 10, 2] (不符合数字大小预期) // 使用比较函数进行数字升序排序 arr.sort((a, b) => a - b); console.log(arr); // [1, 2, 10] // 降序排序 arr.sort((a, b) => b - a); console.log(arr); // [10, 2, 1]
8. copyWithin()
- 作用:浅复制数组的一部分到同一数组中的另一个位置。
-
参数:
-
target
:复制序列到该目标索引位置。 -
start
(可选):开始复制元素的起始索引(默认为 0)。 -
end
(可选):停止复制元素的结束索引(默认为array.length
,不包含此索引)。
-
- 返回值:改变后的原数组。
-
示例:
let arr = [1, 2, 3, 4, 5]; // 将从索引3开始到结束的元素,复制到索引0的位置 arr.copyWithin(0, 3); console.log(arr); // [4, 5, 3, 4, 5]
9. fill()
- 作用:用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。
-
参数:
-
value
:用来填充数组的值。 -
start
(可选):起始索引,默认 0。 -
end
(可选):终止索引(不包含),默认array.length
。
-
- 返回值:修改后的原数组。
-
示例:
let arr = new Array(3); // [empty × 3] arr.fill(0); console.log(arr); // [0, 0, 0] let arr2 = [1, 2, 3, 4]; arr2.fill('a', 1, 3); // 用 'a' 填充索引1到3(不包含3)的位置 console.log(arr2); // [1, 'a', 'a', 4]
二、 不会改变原数组的方法 (Accessor Methods)
这些方法不会修改原始数组,而是返回一个新数组或其它值。
1. concat()
- 作用:用于合并两个或多个数组。
- 参数:数组或值(任意数量)。
- 返回值:一个新的合并后的数组。
-
示例:
let arr1 = [1, 2]; let arr2 = [3, 4]; let newArr = arr1.concat(arr2, 5, [6, 7]); console.log(newArr); // [1, 2, 3, 4, 5, 6, 7] console.log(arr1); // [1, 2] (原数组未变)
2. join()
- 作用:将数组中的所有元素连接成一个字符串。
-
参数(可选):一个字符串,用作分隔符。默认为逗号
,
。 - 返回值:连接后的字符串。
-
示例:
let arr = ['Hello', 'World']; let str1 = arr.join(); let str2 = arr.join(' '); let str3 = arr.join('-'); console.log(str1); // "Hello,World" console.log(str2); // "Hello World" console.log(str3); // "Hello-World"
3. slice()
- 作用:返回一个由** begin 和 end 决定的原数组的浅拷贝**的新数组。
-
参数:
-
begin
(可选):起始索引(包含),默认为 0。负数表示从末尾开始计算。 -
end
(可选):结束索引(不包含),默认为array.length
。负数表示从末尾开始计算。
-
-
返回值:一个新的数组,包含从
start
到end
(不包括end
)的元素。 -
示例:
let arr = ['a', 'b', 'c', 'd', 'e']; let newArr1 = arr.slice(2); // 从索引2开始到结束 console.log(newArr1); // ['c', 'd', 'e'] let newArr2 = arr.slice(1, 4); // 从索引1开始,到索引4(不包含) console.log(newArr2); // ['b', 'c', 'd'] let newArr3 = arr.slice(-2); // 最后两个元素 console.log(newArr3); // ['d', 'e'] console.log(arr); // ['a', 'b', 'c', 'd', 'e'] (原数组未变)
4. indexOf()
- 作用:返回在数组中可以找到给定元素的第一个索引,如果不存在,则返回 -1。
-
参数:
-
searchElement
:要查找的元素。 -
fromIndex
(可选):开始查找的位置。
-
- 返回值:首个被找到的元素的索引,或 -1。
-
示例:
let arr = ['apple', 'banana', 'orange', 'banana']; let index = arr.indexOf('banana'); console.log(index); // 1 let index2 = arr.indexOf('banana', 2); // 从索引2开始找 console.log(index2); // 3 let index3 = arr.indexOf('pear'); console.log(index3); // -1
5. lastIndexOf()
- 作用:返回指定元素在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找。
-
参数:同
indexOf()
。 - 返回值:最后一个被找到的元素的索引,或 -1。
-
示例:
let arr = ['apple', 'banana', 'orange', 'banana']; let index = arr.lastIndexOf('banana'); console.log(index); // 3 (从后往前找,找到最后一个)
6. includes()
- 作用:判断一个数组是否包含一个指定的值。ES2016 新增。
-
参数:
-
valueToFind
:需要查找的元素值。 -
fromIndex
(可选):从该索引处开始查找。
-
-
返回值:布尔值(
true
或false
)。 -
示例:
let arr = [1, 2, 3, NaN]; console.log(arr.includes(2)); // true console.log(arr.includes(4)); // false console.log(arr.includes(NaN)); // true (indexOf无法做到这一点)
三、 迭代方法 (Iteration Methods)
这些方法用于遍历数组,并对每个元素执行提供的函数。
1. forEach()
- 作用:对数组的每个元素执行一次给定的函数。
-
参数:回调函数
(element, index, array) => {}
。 -
返回值:
undefined
。 -
示例:
let arr = [1, 2, 3]; let sum = 0; arr.forEach(function(item) { sum += item; }); console.log(sum); // 6
2. map()
- 作用:创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
-
参数:回调函数
(element, index, array) => newValue
。 - 返回值:一个新的数组,每个元素都是回调函数的返回值。
-
示例:
let arr = [1, 2, 3]; let doubled = arr.map(item => item * 2); console.log(doubled); // [2, 4, 6] console.log(arr); // [1, 2, 3] (原数组未变)
3. filter()
- 作用:创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
-
参数:回调函数
(element, index, array) => boolean
。 - 返回值:一个新的由通过测试的元素组成的数组。如果没有任何元素通过测试,则返回空数组。
-
示例:
let arr = [1, 2, 3, 4, 5, 6]; let evens = arr.filter(item => item % 2 === 0); console.log(evens); // [2, 4, 6]
4. find()
-
作用:返回数组中满足提供的测试函数的第一个元素的值。否则返回
undefined
。ES2015 新增。 -
参数:回调函数
(element, index, array) => boolean
。 -
返回值:数组中第一个满足条件的元素的值,否则返回
undefined
。 -
示例:
let users = [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 3, name: 'Bob' } ]; let user = users.find(user => user.id === 2); console.log(user); // { id: 2, name: 'Jane' }
5. findIndex()
- 作用:返回数组中满足提供的测试函数的第一个元素的索引。否则返回 -1。ES2015 新增。
-
参数:同
find()
。 - 返回值:索引或 -1。
-
示例:
let arr = [5, 12, 8, 130, 44]; let index = arr.findIndex(item => item > 10); console.log(index); // 1 (第一个大于10的元素是12,索引为1)
6. some()
- 作用:测试数组中是不是至少有 1 个元素通过了被提供的函数测试。
-
参数:回调函数
(element, index, array) => boolean
。 -
返回值:布尔值。只要有一个元素通过测试就返回
true
,否则返回false
。 -
示例:
let arr = [1, 2, 3, 4, 5]; let hasEven = arr.some(item => item % 2 === 0); console.log(hasEven); // true (因为有2,4) let hasNegative = arr.some(item => item < 0); console.log(hasNegative); // false
7. every()
- 作用:测试数组的所有元素是否都通过了被提供的函数测试。
-
参数:同
some()
。 -
返回值:布尔值。只有所有元素都通过测试才返回
true
,否则返回false
。 -
示例:
let arr = [2, 4, 6, 8]; let allEven = arr.every(item => item % 2 === 0); console.log(allEven); // true let arr2 = [2, 4, 5, 8]; let allEven2 = arr2.every(item => item % 2 === 0); console.log(allEven2); // false (因为5不是偶数)
8. reduce()
- 作用:对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
-
参数:
- 回调函数
(accumulator, currentValue, index, array) => newAccumulator
。-
accumulator
:累计器,累积回调的返回值。 -
currentValue
:当前正在处理的元素。
-
-
initialValue
(可选):作为第一次调用回调函数时第一个参数的值。强烈建议始终提供。
- 回调函数
- 返回值:使用 reducer 回调函数遍历整个数组后的结果。
-
示例(求和):
let arr = [1, 2, 3, 4]; let sum = arr.reduce((acc, current) => { return acc + current; }, 0); // 初始值设为0 console.log(sum); // 10 // 执行过程: // 第一次: acc=0, current=1 -> return 1 // 第二次: acc=1, current=2 -> return 3 // 第三次: acc=3, current=3 -> return 6 // 第四次: acc=6, current=4 -> return 10
9. reduceRight()
-
作用:与
reduce()
功能相同,但是从数组的末尾向前开始执行。
四、 其他常用方法
1. Array.isArray()
-
作用:用于确定传递的值是否是一个
Array
。这是一个静态方法。 - 参数:需要检测的值。
- 返回值:布尔值。
-
示例:
console.log(Array.isArray([1, 2, 3])); // true console.log(Array.isArray({})); // false console.log(Array.isArray('hello')); // false
2. flat()
- 作用:按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。ES2019 新增。
-
参数(可选):
depth
,指定要提取嵌套数组的结构深度,默认值为 1。使用Infinity
可展开任意深度的嵌套数组。 - 返回值:一个包含将子数组连接后的新数组。
-
示例:
let arr = [1, [2, 3], [4, [5, 6]]]; console.log(arr.flat()); // [1, 2, 3, 4, [5, 6]] (默认深度1) console.log(arr.flat(2)); // [1, 2, 3, 4, 5, 6] (深度2)
3. flatMap()
-
作用:首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与
map()
后接深度为 1 的flat()
几乎相同,但flatMap()
通常在合并成一种方法的效率稍微高一些。ES2019 新增。 -
参数:回调函数
(element, index, array) => newValue
(该返回值应是一个数组)。 - 返回值:一个新的数组,其中每个元素都是回调函数返回的数组连接起来的结果。
-
示例:
let arr = [1, 2, 3]; let result = arr.flatMap(x => [x, x * 2]); // 相当于先 map 成 [[1, 2], [2, 4], [3, 6]],再 flat(1) console.log(result); // [1, 2, 2, 4, 3, 6]
总结与选择
-
想修改原数组:使用
push
,pop
,splice
,sort
,reverse
等。 -
不想修改原数组:使用
concat
,slice
,map
,filter
等。 -
查找元素:
- 找索引:
indexOf
,findIndex
- 找值本身:
find
- 检查是否存在:
includes
,some
- 找索引:
-
检查所有元素:
every
-
遍历数组:
forEach
(无返回值),map
(返回新数组) -
条件筛选:
filter
-
聚合计算:
reduce