1. concat
- 合并数组
语法:
const newArray = oldArray.concat(value1, value2, ..., arrayN);
作用:
将当前数组与其他数组或值合并,返回一个新数组,原数组不变。
测试案例:
const arr1 = [1, 2, 3];
const arr2 = [4, 5];
const arr3 = arr1.concat(arr2, 6); // 合并 arr1、arr2 和数值 6
console.log(arr3); // 输出: [1, 2, 3, 4, 5, 6]
console.log(arr1); // 原数组不变: [1, 2, 3]
扩展:字符串连接
const newString = str1.concat(str2[, str3[, ...[, strN]]]);
str1
:调用concat
方法的原始字符串。str2, str3, ..., strN
:要连接到str1
的字符串。newString
:连接后的新字符串。
测试案例
// 数组连接示例
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [7, 8, 9];
const combinedArray = array1.concat(array2, array3);
console.log(combinedArray); // 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
// 包含非数组值的连接示例
const array4 = [10];
const combinedWithValue = array4.concat(11, [12, 13]);
console.log(combinedWithValue); // 输出: [10, 11, 12, 13]
// 字符串连接示例
const string1 = "Hello";
const string2 = " ";
const string3 = "World";
const combinedString = string1.concat(string2, string3);
console.log(combinedString); // 输出: "Hello World"
2. map - 映射数组
介绍
map
方法会遍历调用它的数组中的每个元素,并对每个元素执行你提供的回调函数。然后,将回调函数的返回值组成一个新的数组并返回,而原数组不会被修改。这在需要对数组中的每个元素进行统一转换或处理时非常有用,比如对数组中的每个数字进行平方运算、将数组中的每个字符串转换为大写等。
语法
// 完整语法(带所有可选参数)
const newArray = 原数组. map(
回调函数(当前元素, [元素索引], [原数组]), // 必传的回调函数(方括号内是可选参数)
[指定回调函数中的this指向] // 可选的this绑定(方括号表示可选)
);
- 核心逻辑:
原数组
调用map
方法,传入一个 必传的回调函数,最终返回一个新数组newArray
。 - 方括号
[]
的含义:表示该参数是 可选的,调用时可以省略(不是必须写)。
const newArray = arr.map(callback(currentValue[, index[, array]])[, thisArg])
arr
:调用map
方法的原数组。callback
:为数组中每个元素执行的函数,该函数接收三个参数:currentValue
:当前正在处理的数组元素。index
(可选):当前正在处理的元素的索引。array
(可选):调用map
方法的数组本身。
thisArg
(可选):执行callback
函数时使用的this
值。
⑴. 必传参数:回调函数 callback
回调函数是 map
的核心,它会对原数组的 每个元素 执行一次,接收 最多 3 个参数(后两个可选):
参数名 | 含义 | 是否必传 | 示例中的体现(假设原数组是 [1,2,3] ) |
---|---|---|---|
currentValue | 当前正在处理的 元素值(比如第一个元素是 1 ,第二个是 2 ) | 必传 | 回调函数的第一个参数永远是它 |
index | 当前元素在 原数组中的索引(第一个元素索引是 0 ,第二个是 1 ) | 可选 | 不写时会被忽略,写了才能使用 |
array | 调用 map 的 原数组本身(即 arr 自己) | 可选 | 很少用,需要操作原数组时才会用到 |
示例(只使用必传的 currentValue
):
const numbers = [1, 2, 3];
const doubled = numbers.map(function (num) { // num 就是 currentValue
return num * 2; // 每个元素乘以2,得到新数组 [2,4,6]
});
示例(同时使用 currentValue 和 index):
const words = ['a', 'b', 'c'];
const withIndex = words.map(function (word, index) { // 第二个参数是索引
return `${index}: ${word}`; // 结果: ['0: a', '1: b', '2: c']
});
⑵. 可选参数:thisArg
(绑定 this
指向)
- 作用:在回调函数中指定
this
的值(很少用,了解即可)。 - 示例(假设需要在回调中使用某个对象的属性):
const obj = { prefix: 'Item ' };
const numbers = [1, 2, 3];
const prefixed = numbers.map(function (num) {
return this.prefix + num; // this 在这里会指向 obj
}, obj); // 第二个参数传入 obj,绑定回调中的 this
console.log(prefixed); // 输出: ['Item 1', 'Item 2', 'Item 3']
总结:
语法:
array.map(callback(element, index, array), thisArg);
作用:
对数组每个元素执行回调函数,返回由回调结果组成的新数组,原数组不变。
测试案例:
const numbers = [1, 2, 3];
const doubled = numbers.map(n => n * 2);
console.log(doubled); // 输出: [2, 4, 6]
console.log(numbers); // 原数组不变: [1, 2, 3]
3. forEach
- 遍历数组
语法:
array.forEach(callback(element, index, array), thisArg);
作用:
遍历数组,为每个元素执行回调函数,无返回值(返回 undefined
),原数组不变。
测试案例:
const fruits = ['apple', 'banana', 'orange'];
fruits.forEach((fruit, index) => {
console.log(`${index}: ${fruit}`);
});
// 输出:
// 0: apple
// 1: banana
// 2: orange
4. reduce
- 累计计算
reduce
方法用于将数组中的元素按顺序逐个处理,通过一个 累加器 累计计算结果,最终返回一个 单一值(可以是数字、字符串、数组、对象等)。
语法:
array.reduce(callback(accumulator, currentValue, index, array), initialValue);
数组.reduce(回调函数(累加器, 当前值, 索引, 原数组), 初始值);
参数说明:
-
回调函数(必传):
对数组中的每个元素执行的函数,接收 最多 4 个参数(后两个可选):- 累加器(accumulator):
上一次回调函数的返回值,初始时是你传入的初始值
(见第 2 点),后续是每次计算的累计结果。 - 当前值(currentValue):
当前正在处理的数组元素(从第一个或第二个元素开始,取决于是否有初始值)。 - 索引(index,可选):
当前元素在原数组中的索引(如果有初始值,第一个元素的索引是0
;如果没有初始值,第一个元素的索引是1
,因为累加器会被赋值为数组的第一个元素)。 - 原数组(array,可选):
调用reduce
方法的数组本身(很少用,按需使用)。
- 累加器(accumulator):
-
初始值(可选):
累加器的 初始状态。如果不传入,默认以数组的 第一个元素 作为初始累加器,且从 第二个元素 开始处理;如果传入,会从 第一个元素 开始处理(累加器初始为你传入的值)。
测试案例:
数组求和(最基础用法)
const numbers = [1, 2, 3, 4];
// 传入初始值 0,累加器从 0 开始,逐个加上当前值
const sum = numbers.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 输出:10
合并数组(将二维数组转一维)
const arrays = [[1, 2], [3, 4], [5, 6]];
const merged = arrays.reduce((acc, cur) => acc.concat(cur), []);
// 初始值是 [],每次把当前数组(cur)拼接到累加器(acc)中
console.log(merged); // 输出:[1, 2, 3, 4, 5, 6]
5.filter
- 过滤数组
筛选出符合回调函数条件的元素,返回新数组,原数组不变。
array.filter(callback(element, index, array), thisArg);
数组.filter(回调函数(元素, 索引, 原数组), 【可选】指定回调中的this指向);
参数详解
必传参数:回调函数 callback
回调函数对原数组的每个元素执行一次,接收 最多 3 个参数(后两个可选),必须返回一个布尔值(true
保留元素,false
排除元素):
参数名 | 含义 | 是否必传 | 示例中的体现(假设原数组是 [1,2,3,4] ) |
---|---|---|---|
element | 当前正在处理的 元素值(比如第一个元素是 1 ,第二个是 2 ) | 必传 | 回调函数的第一个参数永远是它 |
index | 当前元素在 原数组中的索引(第一个元素索引是 0 ,第二个是 1 ) | 可选 | 不写时会被忽略,写了才能使用 |
array | 调用 filter 的 原数组本身(即 arr 自己) | 可选 | 很少用,需要操作原数组时才会用到 |
可选参数:thisArg
(绑定 this
指向)
指定回调函数中 this
的值(实际开发中很少使用,了解即可)。
测试案例:
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(n => n % 2 === 0);
console.log(evenNumbers); // 输出: [2, 4]
console.log(numbers); // 原数组不变: [1, 2, 3, 4, 5]
过滤出长度大于 3 的字符串
const words = ['apple', 'cat', 'banana', 'dog', 'watermelon'];
const longWords = words.filter(word => word.length > 3);
// 回调函数检查字符串长度,保留长度大于 3 的元素
console.log(longWords); // 输出:['apple', 'banana', 'watermelon']
6. join
- 拼接为字符串
语法:
array.join(separator = ',');
作用:
将数组元素按指定分隔符拼接为字符串,原数组不变。
测试案例:
const fruits = ['apple', 'banana', 'orange'];
const str1 = fruits.join(); // 默认分隔符逗号
const str2 = fruits.join(' | '); // 自定义分隔符
console.log(str1); // 输出: "apple,banana,orange"
console.log(str2); // 输出: "apple | banana | orange"
7. find
- 查找元素
语法:
array.find(callback(element, index, array), thisArg);
作用:
返回第一个符合回调条件的元素,若不存在则返回 undefined
,原数组不变。
测试案例:
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
const user = users.find(u => u.id === 2);
console.log(user); // 输出: { id: 2, name: 'Bob' }
8. every
- 检查所有元素
语法:
array.every(callback(element, index, array), thisArg);
作用:
判断所有元素是否都满足回调条件,返回布尔值,原数组不变。
测试案例:
const numbers = [2, 4, 6, 8];
const allEven = numbers.every(n => n % 2 === 0); // 所有数都是偶数
console.log(allEven); // 输出: true
const numbers2 = [2, 3, 4];
const allEven2 = numbers2.every(n => n % 2 === 0); // 存在奇数 3
console.log(allEven2); // 输出: false
9. some
- 检查存在性
语法:
array.some(callback(element, index, array), thisArg);
作用:
判断是否至少有一个元素满足回调条件,返回布尔值,原数组不变。
测试案例:
const numbers = [1, 3, 5, 7];
const hasEven = numbers.some(n => n % 2 === 0); // 不存在偶数
console.log(hasEven); // 输出: false
const numbers2 = [1, 2, 3];
const hasEven2 = numbers2.some(n => n % 2 === 0); // 存在偶数 2
console.log(hasEven2); // 输出: true
10. sort
- 数组排序(原地修改)
语法:
array.sort(compareFunction);
数组.sort(【可选】比较函数(a, b));
参数详解
可选参数:比较函数 (a, b)
决定两个元素的排序顺序,接收两个参数 a
和 b
(代表数组中两个待比较的元素),必须返回一个数值:
- 返回值 < 0:
a
排在b
前面(升序)。 - 返回值 = 0:保持
a
和b
的相对顺序(稳定性,ES6 后保证稳定)。 - 返回值 > 0:
b
排在a
前面(降序)。
如果不传入比较函数,默认按 字符串 Unicode 码点 排序(对数字排序时会出错,见下方示例)。
核心特性:原地修改数组
const numbers = [3, 1, 2];
numbers.sort((a, b) => a - b); // 升序排序
console.log(numbers); // 原数组被修改为 [1, 2, 3]
常见使用场景示例
1. 数字数组升序 / 降序排序
const numbers = [3, 10, 1, 20, 2];
// 升序(a - b:小的在前)
numbers.sort((a, b) => a - b);
console.log(numbers); // 输出:[1, 2, 3, 10, 20]
// 降序(b - a:大的在前)
numbers.sort((a, b) => b - a);
console.log(numbers); // 输出:[20, 10, 3, 2, 1]
2. 字符串数组按字母顺序排序
const fruits = ['banana', 'apple', 'orange', 'grape'];
// 按字母升序(默认规则可省略比较函数,但建议显式写出)
fruits.sort((a, b) => a.localeCompare(b)); // 更安全的字符串排序(考虑语言环境)
console.log(fruits); // 输出:['apple', 'banana', 'grape', 'orange']
3. 注意!默认排序对数字不友好
const nums = [3, 11, 2];
nums.sort(); // 不传入比较函数,按字符串排序('11' < '2' < '3')
console.log(nums); // 输出:['11', '2', '3'](错误!元素被转为字符串比较)
// 正确做法:必须传入数字比较函数
nums.sort((a, b) => a - b);
console.log(nums); // 输出:[2, 3, 11]
11. splice
- 增删改元素(原地修改)
语法:
array.splice(startIndex, deleteCount, item1, item2, ...);
数组.splice(开始索引, 删除数量, 【可选】插入的新元素1, 新元素2, ...);
参数详解
1. 必传参数:startIndex
(开始索引)
- 从数组的哪个位置开始操作,可以是 正数 或 负数:
- 正数:表示从数组的第
startIndex
个元素开始(索引从0
开始,如0
表示第一个元素)。 - 负数:表示从数组末尾倒推的位置(如
-1
表示最后一个元素,-2
表示倒数第二个元素)。 - 如果
startIndex
超过数组长度,会从数组末尾开始操作(相当于在末尾插入或删除)。
- 正数:表示从数组的第
2. 必传参数:deleteCount
(删除数量)
- 需要从
startIndex
位置 删除的元素个数,可以是0
(不删除元素,仅插入新元素):- 若
deleteCount
大于剩余元素数量,会删除从startIndex
到末尾的所有元素。 - 若
deleteCount
为0
,则不会删除元素,仅执行插入操作(见下方示例)。
- 若
3. 可选参数:item1, item2, ...
(插入的新元素)
- 从
startIndex
位置 插入的新元素,可以是任意数量(包括 0 个,即仅删除不插入)。 - 插入的元素会放在被删除元素的位置(如果有删除操作),或直接插入到
startIndex
位置(如果deleteCount
为 0)。
const fruits = ['apple', 'banana', 'orange', 'grape'];
// 删除从索引 2 开始的 1 个元素(删除 'orange')
const deleted = fruits.splice(2, 1);
console.log(fruits); // 输出: ['apple', 'banana', 'grape']
console.log(deleted); // 输出: ['orange']
// 插入新元素:从索引 2 开始,删除 0 个元素,插入 'orange'
fruits.splice(2, 0, 'orange');
console.log(fruits); // 输出: ['apple', 'banana', 'orange', 'grape']
12. reverse
- 反转数组(原地修改)
语法:
array.reverse();
作用:
反转数组元素顺序,原数组被修改,返回反转后的原数组。
测试案例:
const numbers = [1, 2, 3, 4];
numbers.reverse();
console.log(numbers); // 输出: [4, 3, 2, 1]
13. findIndex
- 查找元素索引
语法:
array.findIndex(callback(element, index, array), thisArg);
作用:
返回第一个符合回调条件的元素的索引,若不存在则返回 -1
,原数组不变。
测试案例:
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
const index = users.findIndex(u => u.id === 2);
console.log(index); // 输出: 1(索引从 0 开始)
const notFound = users.findIndex(u => u.id === 3);
console.log(notFound); // 输出: -1(未找到)
14.Array.of()
方法
作用
将一组值(任意数量、任意类型)转换为一个数组。
语法
Array.of(element1, element2, ..., elementN)
特点
- 参数灵活:可以接受任意数量的参数,无论类型或数量。
- 解决
Array
构造函数的歧义:Array(3)
会创建一个长度为3
的空数组[,,]
。Array.of(3)
会直接返回[3]
,避免了Array
构造函数的歧义。
示例
// 基础用法
console.log(Array.of(1, 2, 3)); // [1, 2, 3]
console.log(Array.of("a", true, null)); // ["a", true, null]
console.log(Array.of()); // [](空数组)
// 对比 Array 构造函数
console.log(Array(2)); // [,,](长度为2的空数组)
console.log(Array.of(2)); // [2](数组元素是2)
15.Array.from()
方法
作用
Array.from
是一个 静态方法,用于将 类数组对象(如 arguments
、DOM 节点列表)或 可迭代对象(如 Set
、Map
)转换为 真正的数组,并支持对转换后的元素进行 映射处理。它弥补了传统数组转换方法的不足,提供了更灵活的数组创建方式。
语法
Array.from(类数组或可迭代对象, 【可选】映射函数(元素, 索引), 【可选】指定映射函数中的this指向);
Array.from(arrayLike[, mapFn[, thisArg]])
参数说明
arrayLike
:需要转换的类似数组对象或可迭代对象(如arguments
、NodeList
、字符串、Set
、Map
等)。mapFn
(可选):对每个元素执行的映射函数,类似Array.prototype.map
。thisArg
(可选):映射函数中this
的指向。
特点
- 转换类数组对象:
类数组对象需具备length
属性和索引(如arguments
、document.querySelectorAll
返回的NodeList
)。 - 转换可迭代对象:
如字符串、Set
、Map
等。 - 支持映射操作:
通过mapFn
可在转换时对元素进行处理。
示例
// 转换类数组对象(arguments)
function handleArgs() {
const argsArray = Array.from(arguments);
console.log(argsArray); // [1, 2, 3]
}
handleArgs(1, 2, 3);
// 转换可迭代对象(字符串)
console.log(Array.from("hello")); // ["h", "e", "l", "l", "o"]
// 转换 Set
const set = new Set([1, 2, 3]);
console.log(Array.from(set)); // [1, 2, 3]
// 使用映射函数
const arr = Array.from([1, 2, 3], x => x * 2);
console.log(arr); // [2, 4, 6]
// 处理类似数组但无length的对象(需手动指定length)
console.log(Array.from({0: 'a', 1: 'b', length: 2})); // ["a", "b"]