第六章 JavaScript标准库 6.2 Array 类型

150 阅读30分钟

6.2 Array 类型

数组(Array)是一种常见的数据结构,用于存储一组有序的数据。它可以包含任何数据类型,包括数字、字符串、布尔值、对象等。创建一个数组可以是用方括号语法或者 Array() 构造函数。 使用方括号语法如下: let myArray = []; 也可以在创建数组时同时指定元素,例如: let myArray = ["apple", "banana", "orange"]; 使用 Array() 构造函数语法如下: let myArray = new Array(); 或者指定数组的大小: let myArray = new Array(3); // 创建一个长度为3的数组,元素都为 undefined 同时也可以在创建数组时指定元素: let myArray = new Array("apple", "banana", "orange"); 注意,JavaScript 中的数组可以包含不同的数据类型,像下面这样: let myArray = [ 1, "apple", "banana", "orange"]; 但这并不是一种推荐的使用方式。尽管在某些情况下,将不同的数据类型存储在同一个数组中可能会很方便,但这也可能会导致代码难以维护和调试。本章后边的内容先介绍 2 个 Array 常用的静态方法:

  • 1 Array.from(): 将一个类数组对象或可迭代对象转换成一个新的数组实例。该方法接受两个可选参数,第一个参数指定要转换的对象,第二个参数可以指定一个映射函数,用于将转换前的每个元素转换为转换后的元素。
  • 2 Array.isArray(): 判断一个对象是否是数组。该方法接受一个参数,如果参数是数组,则返回 true,否则返回 false。 再介绍 Array 类型常用的以下实例方法:
  • 1.push(): 在数组末尾添加一个或多个元素,并返回新的长度。
  • 2.pop(): 删除数组末尾的元素,并返回该元素的值。
  • 3.shift(): 删除数组第一个元素,并返回该元素的值。
  • 4.unshift(): 在数组开头添加一个或多个元素,并返回新的长度。
  • 5.concat(): 将两个或多个数组合并成一个新数组。
  • 6.slice(): 从原数组中截取一部分元素组成新的数组。
  • 7.splice(): 在原数组中添加、删除或替换元素。
  • 8.reverse(): 反转数组的顺序。
  • 9.sort(): 对数组进行排序。
  • 10.indexOf(): 返回指定元素在数组中第一次出现的位置,如果不存在返回-1。
  • 11.lastIndexOf(): 返回指定元素在数组中最后一次出现的位置,如果不存在返回-1。
  • 12.join(): 将数组的所有元素转换为字符串并连接起来。
  • 13.toString(): 将数组转换为字符串。
  • 14.forEach(): 遍历数组中的每个元素,并对每个元素执行指定的函数。
  • 15.map(): 遍历数组中的每个元素,并返回一个新数组,新数组的元素为原数组元素经过指定函数处理后的值。
  • 16.filter(): 遍历数组中的每个元素,并返回一个新数组,新数组的元素为原数组中满足指定条件的元素。
  • 17.reduce(): 遍历数组中的每个元素,并将它们合并成一个值。 在学习这些方法的时候关键的是记住他们的参数、返回值类型、是否改变原数组等等。

Array.from

Array.from() 是 JavaScript 中一个用于将类数组对象或可迭代对象(例如 NodeList,Set 等)转换为真正的数组的静态方法。该方法返回一个新数组,其中包含传入对象的所有元素。 Array.from() 接受三个参数:

  • 1.需要转换的对象。
  • 2.可选参数,用于在转换后映射生成的新数组中的每个元素。
  • 3.可选参数,用于在映射过程中定义“this”关键字的值。 下面是一个简单的例子: // 转换一个字符串为数组
const str = 'hello';
const arr = Array.from(str);
console.log(arr); // ['h', 'e', 'l', 'l', 'o']

// 将一个类数组对象转换为数组
const divs = document.querySelectorAll('div');
const arr2 = Array.from(divs);
console.log(arr2); // [div, div, div, ...]

// 将一个可迭代对象转换为数组并映射每个元素
const set = new Set([1, 2, 3]);
const arr3 = Array.from(set, (num) => num * 2);
console.log(arr3); // [2, 4, 6]

function sum() {
  const argsArray = Array.from(arguments); // 将 arguments 转换为数组
  return argsArray.reduce((acc, curr) => acc + curr, 0); // 对数组求和
}
console.log(sum(1, 2, 3)); // 输出 6

Array.isArray

Array.isArray() 是一个用于判断一个值是否为数组的方法,如果是数组则返回 true,否则返回 false。 语法: Array.isArray(value) 其中 value 是需要判断的值。 示例:

Array.isArray([1, 2, 3]); // true
Array.isArray({ foo: 123 }); // false
Array.isArray('bar'); // false
Array.isArray(undefined); // false

该方法是 ES5 引入的,可以在所有现代浏览器和 Node.js 中使用。

push 方法

数组的 push() 方法用于向数组末尾添加一个或多个元素,并返回新数组的长度。push() 方法会修改原始数组,向其末尾添加元素。 push() 方法的语法如下: array.push(element1, element2, ..., elementN) 其中,array 是要添加元素的数组,element1 到 elementN 是要添加的一个或多个元素。 例如,可以使用 push() 方法向数组中添加一个元素:

let myArray = [1, 2, 3];
myArray.push(4);
console.log(myArray); // [1, 2, 3, 4]

也可以向数组中添加多个元素:

let myArray = [1, 2, 3];
myArray.push(4, 5, 6);
console.log(myArray); // [1, 2, 3, 4, 5, 6]

在向数组中添加元素时,可以添加任何 JavaScript 数据类型,包括数字、字符串、布尔值、对象等。 push() 方法还可以在不知道要添加多少个元素的情况下,向数组中添加一个元素。例如:

let myArray = [1, 2, 3];
myArray.push(...[4, 5, 6]);
console.log(myArray); // [1, 2, 3, 4, 5, 6]

在这个例子中,使用 spread 操作符(...)将一个数组 [4, 5, 6] 展开为三个参数,并使用 push() 方法向 myArray 数组中添加这三个参数。

pop 方法

数组的 pop() 方法用于从数组末尾删除一个元素,并返回被删除的元素。pop() 方法会修改原始数组,从其末尾删除元素。 pop() 方法的语法如下: array.pop() 其中,array 是要删除元素的数组。 例如,可以使用 pop() 方法从数组中删除最后一个元素:

let myArray = [1, 2, 3];
let lastElement = myArray.pop();
console.log(myArray); // [1, 2]
console.log(lastElement); // 3

在这个例子中,pop() 方法从 myArray 数组中删除了最后一个元素(即 3),并将其返回给 lastElement 变量。 如果数组为空,则 pop() 方法返回 undefined:

let myArray = [];
let lastElement = myArray.pop();
console.log(myArray); // []
console.log(lastElement); // undefined

shift 方法

数组的 shift() 方法用于从数组开头删除一个元素,并返回被删除的元素。shift() 方法会修改原始数组,从其开头删除元素。 shift() 方法的语法如下: array.shift() 其中,array 是要删除元素的数组。 例如,可以使用 shift() 方法从数组中删除第一个元素:

let myArray = [1, 2, 3];
let firstElement = myArray.shift();
console.log(myArray); // [2, 3]
console.log(firstElement); // 1

在这个例子中,shift() 方法从 myArray 数组中删除了第一个元素(即 1),并将其返回给 firstElement 变量。 如果数组为空,则 shift() 方法返回 undefined:

let myArray = [];
let firstElement = myArray.shift();
console.log(myArray); // []
console.log(firstElement); // undefined

值得注意的是,shift() 方法会改变数组的索引值,因此对于大型数组,使用 shift() 方法会比较耗时。

unshift 方法

数组的 unshift() 方法用于向数组开头添加一个或多个元素,并返回新数组的长度。unshift() 方法会修改原始数组,向其开头添加元素。 unshift() 方法的语法如下: array.unshift(element1, element2, ..., elementN) 其中,array 是要添加元素的数组,element1 到 elementN 是要添加的一个或多个元素。 例如,可以使用 unshift() 方法向数组中添加一个元素:

let myArray = [1, 2, 3];
myArray.unshift(0);
console.log(myArray); // [0, 1, 2, 3]

也可以向数组中添加多个元素:

let myArray = [1, 2, 3];
myArray.unshift(-2, -1, 0);
console.log(myArray); // [-2, -1, 0, 1, 2, 3]

在向数组中添加元素时,可以添加任何 JavaScript 数据类型,包括数字、字符串、布尔值、对象等。 unshift() 方法还可以在不知道要添加多少个元素的情况下,向数组开头添加一个元素。例如:

let myArray = [1, 2, 3];
myArray.unshift(...[0, -1, -2]);
console.log(myArray); // [-2, -1, 0, 1, 2, 3]

在这个例子中,使用 spread 操作符(...)将一个数组 [0, -1, -2] 展开为三个参数,并使用 unshift() 方法向 myArray 数组中添加这三个参数。

concat 方法

数组的 concat() 方法用于将一个或多个数组合并成一个新数组。concat() 方法不会修改原始数组,而是返回一个新的数组,其中包含合并的元素。 concat() 方法的语法如下: array.concat(array1, array2, ..., arrayN) 其中,array 是要合并的数组,array1 到 arrayN 是要合并的一个或多个数组。 例如,可以使用 concat() 方法将两个数组合并成一个新数组:

let myArray1 = [1, 2, 3];
let myArray2 = [4, 5, 6];
let mergedArray = myArray1.concat(myArray2);
console.log(mergedArray); // [1, 2, 3, 4, 5, 6]

也可以将多个数组合并成一个新数组:

let myArray1 = [1, 2, 3];
let myArray2 = [4, 5, 6];
let myArray3 = [7, 8, 9];
let mergedArray = myArray1.concat(myArray2, myArray3);
console.log(mergedArray); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

再看下边一个例子,数据的元素还是数组的时候,concat() 方法不会递归地展开嵌套的数组。

let arr1 = [1, 2];
let arr2 = [3, [4, 5]];

let result = arr1.concat(arr2);

console.log(result); // [1, 2, 3, [4, 5]]

在这个例子中,arr1 是包含两个元素的数组 [1, 2],而 arr2 是包含两个元素的数组 [3, [4, 5]],其中第二个元素是另一个数组 [4, 5]。 当我们使用 concat() 方法将 arr1 和 arr2 合并时,结果是一个新的数组,该数组包含原始数组的所有元素。因此,结果数组是 [1, 2, 3, [4, 5]]。 需要注意的是,concat() 方法不会递归地展开嵌套的数组。如果被合并的数组中包含其他数组,则这些数组将被视为单个元素,并添加到新数组中。在这个例子中,[4, 5] 被视为一个单独的元素,并作为整个数组添加到结果数组中。

slice 方法

slice() 方法用于返回一个数组的一部分,而不会修改原始数组。它接受两个参数:起始索引和终止索引(不包括终止索引)。 语法如下: array.slice(startIndex, endIndex) 其中,startIndex 是要提取的起始索引(从 0 开始计数),endIndex 是要提取的终止索引(不包括该索引对应的元素)。如果省略 endIndex 参数,则 slice() 方法将返回从 startIndex 开始到数组末尾的所有元素。如果不传任何参数则对数组不做任何操作。 下面是一个使用 slice() 方法的例子:

let arr = [1, 2, 3, 4, 5];
let slicedArr = arr.slice(1, 4);
let sliceArr2 = arr.slice();

console.log(slicedArr); // [2, 3, 4]
console.log(sliceArr2); // [1, 2, 3, 4, 5]

在这个例子中,arr 是一个包含 5 个元素的数组。我们使用 slice() 方法提取索引从 1 到 4(不包括索引为 4 的元素)的元素。因此,slicedArr 包含索引 1、2 和 3 对应的元素 [2, 3, 4]。如果省略参数或参数无效,则会返回一个空数组。 slice() 方法的 startIndex 参数也可以是负数,这将从数组的末尾开始计算索引。例如,如果 startIndex 参数为 -2,则提取的起始索引将是数组的倒数第二个元素。 下面是一个使用负数 startIndex 参数的例子:

let arr = [1, 2, 3, 4, 5];
let slicedArr = arr.slice(-3);

console.log(slicedArr); // [3, 4, 5]

在这个例子中,startIndex 参数为 -3,这意味着要从数组的倒数第三个元素开始提取。因此,slicedArr 包含最后三个元素 [3, 4, 5]。

splice 方法

splice() 方法用于在数组中插入或删除元素,同时修改原始数组。它接受多个参数:起始索引、要删除的元素个数和要插入的元素。 语法如下: array.splice(startIndex, deleteCount, item1, item2, ...) 其中,startIndex 是要修改的起始索引,deleteCount 是要删除的元素个数,item1, item2, ... 是要插入到数组中的元素。 如果 deleteCount 参数为 0,则不删除任何元素,只插入新元素。如果省略 deleteCount 参数,则将删除从 startIndex 开始到数组末尾的所有元素。如果省略 item1, item2, ... 参数,则 splice() 方法只删除元素,而不插入新元素。它返回一个包含删除的元素的新数组。如果不删除任何元素,则返回一个空数组。 下面是一些使用 splice() 方法的例子:

let arr = [1, 2, 3, 4, 5];
arr.splice(1, 2); // 删除从索引 1 开始的 2 个元素
console.log(arr); // [1, 4, 5]

let arr2 = [1, 2, 3, 4, 5];
arr2.splice(2, 0, 'a', 'b'); // 从索引 2 开始插入 'a' 和 'b'
console.log(arr2); // [1, 2, 'a', 'b', 3, 4, 5]

let arr3 = [1, 2, 3, 4, 5];
arr3.splice(1, 3, 'a', 'b'); // 从索引 1 开始删除 3 个元素,并插入 'a' 和 'b'
console.log(arr3); // [1, 'a', 'b', 5]

在第一个例子中,我们从索引 1 开始删除 2 个元素,因此数组变为 [1, 4, 5]。 在第二个例子中,我们从索引 2 开始插入 'a' 和 'b',因此数组变为 [1, 2, 'a', 'b', 3, 4, 5]。 在第三个例子中,我们从索引 1 开始删除 3 个元素,并插入 'a' 和 'b',因此数组变为 [1, 'a', 'b', 5]。

reverse 方法

reverse()用于将数组中的元素颠倒顺序,即将最后一个元素变为第一个,将倒数第二个元素变为第二个,以此类推。reverse() 方法没有参数,会修改原始数组,同时返回颠倒顺序后的数组。 语法如下: array.reverse() reverse() 方法不接收任何参数,直接在原始数组上操作。 下面是一个使用 reverse() 方法的示例:

let arr = [1, 2, 3, 4, 5];
arr.reverse();
console.log(arr); // [5, 4, 3, 2, 1]

在这个例子中,我们将数组 [1, 2, 3, 4, 5] 反转,得到了 [5, 4, 3, 2, 1]。 如果不想改变原始数组的话,可以先使用 slice() 方法创建原始数组的副本,然后再使用 reverse() 方法。例如:

let arr = [1, 2, 3, 4, 5];
let reversedArr = arr.slice().reverse();
console.log(arr); // [1, 2, 3, 4, 5]
console.log(reversedArr); // [5, 4, 3, 2, 1]

在这个示例中,我们首先使用 slice() 方法创建了原始数组 arr 的副本 reversedArr,然后对副本数组调用 reverse() 方法,得到了一个反转后的新数组,而原始数组 arr 保持不变。

sort 方法

sort() 方法是 JavaScript 数组的一个内置方法,用于对数组中的元素进行排序。sort() 方法会修改原始数组,同时返回排序后的数组。 语法如下: array.sort([compareFunction]) 其中,compareFunction 是一个可选的函数,用于指定排序顺序。如果省略该参数,则按照 Unicode 编码进行排序。 下面是一个使用 sort() 方法的示例:

let arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
arr.sort();
console.log(arr); // [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]

在这个例子中,我们对数组 [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] 进行了排序,得到了 [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]。由于没有传递 compareFunction 参数,因此按照 Unicode 编码进行排序。 按照 Unicode 编码进行排序指的是,JavaScript 在执行数组排序时,默认会将数组中的每个元素都转换为 Unicode 字符串,然后按照这些字符串的字典序进行排序。举个例子,如果要对字符串数组进行排序,数组元素为 ["apple", "orange", "banana", "cherry"],使用默认的 sort() 方法进行排序,那么排序结果是 ["apple", "banana", "cherry", "orange"]。这是因为在 Unicode 编码中,字母 "a" 的编码值小于字母 "b" 的编码值,因此 "apple" 会排在 "banana" 的前面,以此类推。 对于数字数组,如果直接使用默认的 sort() 方法进行排序,可能会得到不正确的结果。例如,对于数字数组 [3, 15, 1, 6, 9, 2],使用默认的 sort() 方法进行排序,结果是 [1, 15, 2, 3, 6, 9]。这是因为默认的 sort() 方法会将数字转换为字符串,然后使用 Unicode 编码进行比较。在字符串比较中,"15" 会排在 "2" 的前面,因此结果就不正确了。为了解决这个问题,可以使用自定义的 compareFunction 参数,指定按照数字大小进行比较。compareFunction 函数接收两个参数,分别表示数组中要比较的两个元素,函数应该返回一个值,表示这两个元素的大小关系。如果返回值小于 0,则表示第一个元素应该排在第二个元素前面;如果返回值大于 0,则表示第二个元素应该排在第一个元素前面;如果返回值等于 0,则表示这两个元素的相对位置不变。所以如果要对数字数组按照从小到大的顺序进行排序,可以定义一个简单的 compareNumbers 函数,然后传给 sort 方法,如下所示:

function compareNumbers(a, b) {
  return a - b;
}

let arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
arr.sort(compareNumbers);
console.log(arr); // [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]

indexOf 方法

indexOf() 方法用于返回数组中指定元素的第一个匹配项的索引。如果数组中不存在该元素,则返回 -1。 语法: array.indexOf(searchElement[, fromIndex]) 参数:

  • 1 searchElement:要查找的元素。
  • 2 fromIndex(可选):从该索引处开始查找。如果省略此参数,则从数组的开头开始查找。如果 fromIndex 大于等于数组的长度,则返回 -1,表示未找到该元素。如果 fromIndex 是一个负数,则从数组末尾开始倒数查找。 示例:
const arr = [1, 2, 3, 4, 5];

console.log(arr.indexOf(3)); // 2
console.log(arr.indexOf(6)); // -1
console.log(arr.indexOf(2, 2)); // -1
console.log(arr.indexOf(2, -3)); // 1

在第一个示例中,indexOf(3) 返回数组中值为 3 的第一个元素的索引,即 2。 在第二个示例中,indexOf(6) 返回 -1,因为数组中没有值为 6 的元素。 在第三个示例中,indexOf(2, 2) 从索引 2 开始查找数组中值为 2 的第一个元素,但由于此元素位于索引 1 处,因此未找到该元素。 在第四个示例中,indexOf(2, -3) 从倒数第三个元素开始查找数组中值为 2 的第一个元素,找到了位于索引 1 处的元素。

lastIndexOf 方法

lastIndexOf() 方法与 indexOf() 方法类似,但是它返回的是指定元素在数组中最后一次出现的索引。如果数组中不存在该元素,则返回 -1。 语法: array.lastIndexOf(searchElement[, fromIndex]) 参数:

  • 1 searchElement:要查找的元素。
  • 2 fromIndex(可选):从该索引处开始反向查找。如果省略此参数,则从数组的末尾开始查找。如果 fromIndex 大于等于数组的长度,则整个数组都会被查找。如果 fromIndex 是一个负数,则从数组末尾的倒数第几个元素开始反向查找。 示例:
const arr = [1, 2, 3, 4, 5, 2];

console.log(arr.lastIndexOf(2)); // 5
console.log(arr.lastIndexOf(6)); // -1
console.log(arr.lastIndexOf(2, 2)); // 1
console.log(arr.lastIndexOf(2, -3)); // 1

在第一个示例中,lastIndexOf(2) 返回数组中值为 2 的最后一个元素的索引,即 5。 在第二个示例中,lastIndexOf(6) 返回 -1,因为数组中没有值为 6 的元素。 在第三个示例中,lastIndexOf(2, 2) 从索引 2 开始反向查找数组中值为 2 的最后一个元素,但由于此元素位于索引 1 处,因此未找到该元素。 在第四个示例中,lastIndexOf(2, -3) 从倒数第三个元素开始反向查找数组中值为 2 的最后一个元素,找到了位于索引 1 处的元素。

join 方法

join() 方法将一个数组的所有元素转化为一个字符串,并返回该字符串。可以指定一个可选的字符串作为分隔符,将数组中的元素分隔开来。如果不指定分隔符,则默认使用逗号(,)作为分隔符。 语法: array.join([separator]) 参数: separator(可选):用于分隔每个数组元素的字符串。如果省略该参数,则使用默认分隔符逗号(,)。 示例:

const arr = ['apple', 'banana', 'orange'];

console.log(arr.join()); // "apple,banana,orange"
console.log(arr.join('-')); // "apple-banana-orange"
console.log(arr.join(' and ')); // "apple and banana and orange"

在第一个示例中,join() 方法将数组中的所有元素使用默认分隔符逗号(,)连接成一个字符串。 在第二个示例中,join("-") 将数组中的所有元素使用分隔符 - 连接成一个字符串。 在第三个示例中,join(" and ") 将数组中的所有元素使用分隔符 and 连接成一个字符串。

toString 方法

toString() 方法将一个数组的所有元素转化为一个字符串,并返回该字符串。与 join() 方法不同的是,toString() 方法不支持指定分隔符。 语法: array.toString() 示例:

const arr = ['apple', 'banana', 'orange'];
console.log(arr.toString()); // "apple,banana,orange"

在示例中,toString() 方法将数组中的所有元素使用默认分隔符逗号(,)连接成一个字符串。

forEach 方法

forEach() 方法用于遍历数组中的每个元素,对每个元素执行指定操作,它不会改变原数组,并且无法使用 break 语句跳出循环,但可以使用 return 语句跳出当前循环。 语法: array.forEach(callback(currentValue, index, array)) 参数: 1 callback:对数组中的每个元素执行的函数。 2 currentValue:当前正在处理的元素。 3 index(可选):当前正在处理的元素的索引。 4 array(可选):调用该方法的数组。 示例: const arr = [1, 2, 3];

arr.forEach(function(item, index) { console.log(arr[${index}] = ${item}); });

// Output: // arr[0] = 1 // arr[1] = 2 // arr[2] = 3

在示例中,forEach() 方法遍历数组 arr 中的每个元素,并执行传递给它的回调函数。在回调函数中,我们可以访问当前正在处理的元素和它的索引。在这个例子中,我们将数组中的每个元素和它的索引打印到控制台上。 map 方法 map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。map() 方法不会修改原始数组,而是返回一个新的数组。 语法: array.map(callback(currentValue, index, array)) 参数:

  • 1 callback:生成新数组元素的函数。
  • 2 currentValue:当前正在处理的元素。
  • 3 index(可选):当前正在处理的元素的索引。
  • 4 array(可选):调用该方法的数组。 返回值:由原数组每个元素调用 callback 函数后的返回值组成的新数组。 例如,假设有一个数组 numbers: const numbers = [1, 2, 3, 4, 5]; 如果我们想将该数组中的每个元素都乘以 2 并返回一个新的数组,可以使用 map() 方法:
const doubled = numbers.map(function (number) {
  return number * 2;
});

console.log(doubled); // [2, 4, 6, 8, 10]

另外,由于 map() 方法返回的是一个新的数组,因此原数组不会被修改。 如果使用箭头函数的话,可以写成更简洁的形式: const doubled = numbers.map(number => number * 2); 需要注意的是,map() 方法返回的新数组的长度与原数组的长度相同。如果在回调函数中省略了 return 语句,返回的新数组中对应的元素值为 undefined。

const numbers = [1, 2, 3];
const mapped = numbers.map(function (number) {
  // 没有返回语句
});
console.log(mapped); // [undefined, undefined, undefined]

filter 方法

filter() 是 Array 原型上的一个方法,它创建一个新的数组,其中包含通过给定函数测试的所有元素。它接受一个回调函数作为参数,该函数将被应用于数组的每个元素。该回调函数返回一个布尔值,用于指示元素是否应包含在过滤后的数组中。如果回调函数返回 true,则元素将包含在结果数组中,否则将被过滤掉。 filter() 方法的语法如下: arr.filter(callback(element[, index[, array]])[, thisArg]) 其中,callback 是一个回调函数,它的参数如下:

  • 1 element:表示当前正在处理的元素。
  • 2 index(可选):表示当前正在处理的元素的索引。
  • 3 array(可选):表示调用 filter() 方法的数组本身。
  • 4 thisArg(可选):表示回调函数中 this 关键字的值。 下面是一个使用 filter() 方法的例子:
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(function (num) {
  return num % 2 === 0;
});
console.log(evenNumbers); // [2, 4]

在上面的例子中,filter() 方法接受一个回调函数,该函数检查每个元素是否为偶数,并返回一个布尔值。返回值为 true 的元素将被包含在结果数组 evenNumbers 中。 除了使用普通函数作为回调函数,还可以使用箭头函数,如下所示:

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter((num) => num % 2 === 0);
console.log(evenNumbers); // [2, 4]

filter() 方法不会修改原始数组,而是返回一个新的过滤后的数组。如果原始数组包含 undefined 或 null 元素,它们也将包含在过滤后的数组中。 注意,如果数组中的元素是对象,filter() 方法仅返回与原始数组中相同的对象引用,而不是新的对象。如果需要返回新的对象,需要在回调函数中进行深拷贝。 filter(Boolean) 是一个常见的用法,它可以用来过滤掉数组中的 falsy 值。 falsy 是一个 JavaScript 中的概念,指代那些在布尔上下文中被当作 false 的值。在 JavaScript 中,以下值被视为 falsy 值:

  • 1 false:布尔值 false
  • 2 0:数字 0
  • 3 '':空字符串
  • 4 null:表示无值的特殊关键字
  • 5 undefined:表示未定义的特殊关键字
  • 6 NaN:表示非数字值的特殊值 这些值在 JavaScript 中被视为 false。 当 Boolean 函数作为 filter 方法的参数时,它会被自动调用,并将每个元素作为参数传入。Boolean 函数会将传入的值转换成布尔值,如果值为 falsy,就返回 false,否则返回 true。因此,filter(Boolean) 等价于过滤掉所有 falsy 值的数组。 假设有一个数组 arr 包含以下元素:[0, 1, 2, '', 'hello', null, undefined, NaN, 3],我们想要过滤掉其中的 falsy 值。可以使用以下代码:
const arr = [0, 1, 2, '', 'hello', null, undefined, NaN, 3];
const filteredArr = arr.filter(Boolean);
console.log(filteredArr); // [1, 2, 'hello', 3]

在这个例子中,Boolean 函数被用作 filter 方法的参数,自动调用并将数组中的每个元素作为参数传入,返回值为布尔值。在执行 filter(Boolean) 后,所有 falsy 值 0、''、null、undefined 和 NaN 都被过滤掉了,只剩下了 1、2、'hello' 和 3,它们被保存在 filteredArr 数组中。

reduce 方法

reduce() 是 JavaScript 数组对象中的方法,用于对数组中的所有元素执行一个归纳(或者叫 reduce)操作,然后返回一个结果。它接受一个回调函数作为参数,该回调函数会被依次应用于数组中的每个元素。在每次调用回调函数时,reduce() 函数会传递两个参数:累积值和当前值。 reduce() 方法的语法如下: arr.reduce(callback[, initialValue]); 其中,callback 是一个回调函数,它会被传递三个参数:

  • 1 accumulator:累加器,它是回调函数的第一个参数,用于累积回调函数的返回值。
  • 2 currentValue:当前值,它是回调函数的第二个参数,表示当前正在被处理的元素。
  • 3 currentIndex:当前索引,它是回调函数的第三个参数,表示当前正在被处理的元素的索引。 另外,initialValue 参数是可选的,它指定第一次调用回调函数时累加器的初始值。如果省略了该参数,则会使用数组的第一个元素作为初始值。 reduce() 方法会遍历数组中的每个元素,并且将每个元素和累加器传递给回调函数。回调函数执行后返回一个新的累加器值,该值会在下一次调用回调函数时作为累加器的值。最后,reduce() 方法返回最后一次调用回调函数后的累加器的值。 下面是一个简单的 reduce() 方法的示例:
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => {
  return accumulator + currentValue;
});
console.log(sum); // 15

在这个例子中,reduce() 方法会对数组中的每个元素执行加法操作,并将结果累加到一个变量中,最后返回该变量的值。由于省略了 initialValue 参数,因此累加器的初始值为数组中的第一个元素(即 1)。在第一次调用回调函数时,accumulator 的值为 1,currentValue 的值为 2,回调函数返回 3,因此累加器的值变为 3。在第二次调用回调函数时,accumulator 的值为 3,currentValue 的值为 3,回调函数返回 6,因此累加器的值变为 6。以此类推,直到遍历完整个数组并返回最终的累加器值 15。 初始值 10 的例子如下:

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, curr) => acc + curr, 10);
console.log(sum); // 25

这里的 reduce 方法将数组 numbers 中的所有元素相加,并加上初始值 10。初始值 10 被赋给 acc 参数,curr 参数则分别为数组中的元素 1、2、3、4、5。通过每次计算返回的结果不断累加到下一次的 acc 参数中,最终得到结果 25。

reduceRight 方法

reduceRight() 方法与 reduce() 方法类似,但是它从数组的末尾开始遍历元素,而不是从头开始。具体来说,它会对数组中的每个元素(从右到左)执行提供的回调函数,并将上一次回调的结果传递给下一次回调。最终返回回调函数的最后一个调用的返回值。 reduceRight() 方法的语法如下: arr.reduceRight(callback[, initialValue]) 其中,callback 是一个用来处理数组中每个元素的函数。这个函数接收四个参数:

  • 1 accumulator:累加器累计回调函数的返回值。它是上一次调用回调函数时返回的累积值,或者是传递给 reduce() 方法的初始值(如果指定了)。
  • 2 currentValue:数组中正在处理的元素。
  • 3 currentIndex(可选):当前元素在数组中的索引。
  • 4 array(可选):正在操作的数组。 与 reduce() 方法一样,reduceRight() 方法也可以接收一个可选的初始值 initialValue,如果提供了这个值,则作为第一次调用回调函数时的第一个参数传递进去。如果没有提供初始值,则使用数组中最后一个元素作为初始值,并从数组倒数第二个元素开始执行回调函数。 下面是一个简单的示例,使用 reduceRight() 方法计算数组中所有元素的乘积:
const arr = [1, 2, 3, 4, 5];
const product = arr.reduceRight((accumulator, currentValue) => {
  return accumulator * currentValue;
});
console.log(product); // 输出 120

在这个例子中,reduceRight() 方法从数组的最后一个元素开始遍历,首先将最后一个元素 5 作为累加器的初始值,然后将累加器和前一个元素 4 传递给回调函数。回调函数将它们相乘得到 20,然后将 20 和前一个元素 3 传递给回调函数。以此类推,直到遍历完整个数组,得到最终的乘积 120。

every 方法

every() 方法用于检测数组中的所有元素是否都满足指定条件,返回一个布尔值。如果数组中的每个元素都符合指定条件,那么 every() 方法返回 true,否则返回 false。 every() 方法接受一个回调函数作为参数,这个回调函数会接受三个参数:

  • 1 element:当前正在处理的数组元素
  • 2 index:当前正在处理的元素在数组中的索引
  • 3 array:调用 every() 方法的数组对象 回调函数需要返回一个布尔值,如果返回 true,表示当前元素符合条件,every() 方法会继续处理下一个元素。如果返回 false,则 every() 方法会立即停止处理,返回 false。 示例:
const ages = [18, 20, 22, 24, 26];
const allAreAdults = ages.every(function (age) {
  return age >= 18;
});
console.log(allAreAdults); // true

上述代码中,every() 方法检查了数组 ages 中的每个元素,检查它们是否都大于等于 18,由于所有元素都符合条件,所以 every() 方法返回了 true。

some 方法

some() 方法用于检查数组中是否至少有一个元素满足指定条件。它会返回一个布尔值,如果至少有一个元素满足条件则返回 true,否则返回 false。 some() 方法接受一个函数作为参数,该函数用于测试数组中的每个元素是否满足指定条件。这个测试函数可以接受三个参数:

  • 1 currentValue:当前被测试的元素。
  • 2 index(可选):当前被测试的元素在数组中的索引。
  • 3 array(可选):被测试的数组。 如果测试函数返回 true,则 some() 方法立即返回 true,并且不再对剩下的元素进行测试。如果所有元素都被测试了,但是没有一个元素满足条件,则 some() 方法返回 false。 以下是 some() 方法的语法: arr.some(callback(element[, index[, array]])[, thisArg]) 其中:
  • 1 arr:要操作的数组。
  • 2 callback:用来测试数组中每个元素的函数。
  • 3 element:当前被测试的元素。
  • 4 index:当前被测试的元素在数组中的索引。
  • 5 array:被测试的数组。
  • 6 thisArg:执行 callback 函数时使用的 this 值。 下面是一个示例,使用 some() 方法来检查数组中是否包含偶数:
const numbers = [1, 3, 5, 7, 8, 9];
const hasEvenNumber = numbers.some((number) => number % 2 === 0);
console.log(hasEvenNumber); // true

在这个例子中,我们首先定义了一个数组 numbers,它包含了一些奇数和偶数。然后我们使用 some() 方法来检查数组中是否包含偶数。我们传递了一个函数作为 some() 方法的参数,这个函数测试每个数组元素是否是偶数,如果找到任意一个偶数,则返回 true。在这个例子中,我们找到了数字 8 是偶数,所以 some() 方法返回 true。

find 方法

find 方法返回数组中第一个满足提供的测试函数的元素的值。否则返回 undefined。 该方法接收一个回调函数作为参数,这个回调函数会遍历数组中的每一个元素,如果回调函数返回 true,则返回该元素的值;否则继续遍历数组直到找到符合条件的元素或者遍历结束。 该方法的语法如下: arr.find(callback[, thisArg]) 其中,callback 是一个用于测试每个元素的函数,它可以接收三个参数: 1 element:表示当前正在处理的元素。 2 index:表示当前正在处理的元素的索引。 3 array:表示当前数组对象。 thisArg 是可选的,它表示回调函数执行时 this 的值。 举个例子,假设我们有一个数组 students,每个元素都是一个包含学生信息的对象,包括姓名和分数。我们想找到分数大于等于 80 分的学生信息。可以这样写:

const students = [
  { name: 'Alice', score: 75 },
  { name: 'Bob', score: 92 },
  { name: 'Charlie', score: 87 },
  { name: 'David', score: 68 },
];
const result = students.find((student) => student.score >= 80);
console.log(result); // { name: 'Bob', score: 92 }

在这个例子中,我们使用 find 方法找到了第一个分数大于等于 80 分的学生信息,即 Bob 的信息。 需要注意的是,find 方法只返回满足条件的第一个元素,如果有多个元素满足条件,也只返回第一个,不会返回所有满足条件的元素。如果没有元素满足条件,则返回 undefined。 另外,find 方法只对数组中的每个元素执行一次回调函数,如果数组发生改变,find 方法遍历的元素顺序不会受到影响,但是遍历的元素个数可能会受到影响。