数组方法
Array.prototype@@iterator
Array 实例的 [@@iterator]()
方法实现了迭代协议,允许数组被大多数期望可迭代对象的语法所使用,例如展开语法和 for…of 循环。它返回一个数组迭代器对象 (en-US),该对象会产生数组中每个索引的值。
该属性的初始值与 Array.prototype.values 属性的初始值是相同的函数对象。
array[Symbol.iterator]()
Array.prototype.at()
at()
方法接收一个整数值并返回该索引对应的元素,允许正数和负数。负整数从数组中的最后一个元素开始倒数。
在传递非负数时,at() 方法等价于括号表示法。例如,array[0] 和 array.at(0) 均返回第一个元素。但是,当你需要从数组的末端开始倒数时,则不能使用 Python 和 R 语言中支持的 array[-1],因为方括号内的所有值都会被视为字符串属性,因此你最终读取的是 array[“-1”],这只是一个普通的字符串属性而不是数组索引。
通常的做法是访问 length 并将其减去从末端开始的相对索引。例如,array[array.length - 1]。at() 方法允许使用相对索引,因此上面的示例可以简化为 array.at(-1)。
at() 方法是通用的。其仅期望 this 具有 length 属性和以整数为键的属性。
// 数组及数组元素
const cart = ["apple", "banana", "pear"];
// 一个函数,用于返回给定数组的最后一个元素
function returnLast(arr) {
return arr.at(-1);
}
// 获取 'cart' 数组的最后一个元素
const item1 = returnLast(cart);
console.log(item1); // 输出:'pear'
// 在 'cart' 数组中添加一个元素
cart.push("orange");
const item2 = returnLast(cart);
console.log(item2); // 输出:'orange'
Array.prototype.concat()
concat()
方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
concat 方法创建一个新数组。该数组将首先由调用它的对象中的元素填充。然后,对于每个参数,它的值将被连接到数组中——对于普通对象或基元,参数本身将成为最终数组的一个元素;对于属性Symbol.isConcatSpreadable设置为真的数组或类数组对象,参数的每个元素都将是独立地添加到最终数组中。concat 方法不会递归到嵌套数组参数中。
concat() 方法是一种复制方法。它不会更改 this 或作为参数提供的任何数组,而是返回包含与原始数组中的元素相同的元素的浅拷贝。
如果任何源数组是稀疏数组,concat() 方法会保留空槽。
concat() 方法是通用的。this 值的处理方式与其他参数相同(除了它会先转换为对象),这意味着普通对象将直接添加到结果数组中,而 @@isConcatSpreadable 属性为真值的类数组对象将展开并添加到数组中。
const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);
console.log(array3);
// Expected output: Array ["a", "b", "c", "d", "e", "f"]
Array.prototype.copyWithin()
copyWithin()
方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
copyWithin() 方法的工作原理类似于 C 和 C++ 的 memmove,是一种移动数组数据的高性能方法,与 TypedArray 的同名方法类似。序列在一次中操作被复制和粘贴;即使复制和粘贴区域重叠,粘贴的序列也将具有复制值。
copyWithin() 是修改方法。它不会改变 this 指向的对象(数组或类数组)的长度,但会更改其的内容,并在必要时创建新属性或删除现有属性。
copyWithin() 方法保留空槽。如果要复制的区域是稀疏的,则原来的空槽会被删除并被替换为拷贝的空槽。
copyWithin() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。虽然字符串也是类似数组的,但这种方法不适用于它们,因为字符串是不可变的。
console.log([1, 2, 3, 4, 5].copyWithin(-2));
// [1, 2, 3, 1, 2]
console.log([1, 2, 3, 4, 5].copyWithin(0, 3));
// [4, 5, 3, 4, 5]
console.log([1, 2, 3, 4, 5].copyWithin(0, 3, 4));
// [4, 2, 3, 4, 5]
console.log([1, 2, 3, 4, 5].copyWithin(-2, -3, -1));
// [1, 2, 3, 3, 4]
Array.prototype.entries()
entries()
方法返回一个新的数组迭代器对象,该对象包含数组中每个索引的键/值对。
当在稀疏数组上使用时,entries() 方法迭代空槽,就像它们的值为 undefined 一样。
entries() 方法是通用的。它只要求 this 值具有 length 属性和以整数为键的属性。
const array1 = ['a', 'b', 'c'];
const iterator1 = array1.entries();
console.log(iterator1.next().value);
// Expected output: Array [0, "a"]
console.log(iterator1.next().value);
// Expected output: Array [1, "b"]
Array.prototype.every()
every()
方法测试一个数组内的所有元素是否都能通过指定函数的测试。它返回一个布尔值。
every() 方法是一个迭代方法。它为数组中的每个元素调用一次指定的 callbackFn 函数,直到 callbackFn 返回一个假值。如果找到这样的元素,every() 方法将会立即返回 false 并停止遍历数组。否则,如果 callbackFn 为每个元素返回一个真值,every() 就会返回 true。
every 和数学中的全称量词"任意(∀)"类似。特别的,对于空数组,它只返回 true。(这种情况属于无条件正确,因为空集的所有元素都符合给定的条件。)
callbackFn 仅针对已分配值的数组索引调用。它不会为稀疏数组中的空槽调用。
every() 不会改变调用它的数组,但指定的 callbackFn 函数可以。但是请注意,数组的长度是在第一次调用 callbackFn 之前保存的。所以:
- 当开始调用 every() 时,callbackFn 将不会访问超出数组初始长度的任何元素。
- 对已访问索引的更改不会导致再次在这些元素上调用 callbackFn。
- 如果数组中一个现有的、尚未访问的元素被 callbackFn 更改,则它传递给 callbackFn 的值将是该元素被修改后的值。被删除的元素则不会被访问。
const isBelowThreshold = (currentValue) => currentValue < 40;
const array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every(isBelowThreshold));
// Expected output: true
Array.prototype.fill()
fill()
方法用一个固定值填充一个数组中从起始索引(默认为 0
)到终止索引(默认为 array.length
)内的全部元素。它返回修改后的数组。
fill() 是个修改方法,不会改变 this 的长度,但会改变 this 的内容。
fill() 也会使用 value 填充稀疏数组的空槽。
fill() 方法是通用的。它只期望 this 值有一个 length 属性。虽然字符串也是类似数组的,但这个方法不适合应用于它们,因为字符串是不可变的。
在一个空数组(
length = 0
)上使用Array.prototype.fill()
不会对其进行修改,因为数组没有要修改的内容。要在声明一个数组时使用Array.prototype.fill()
,请确保数组的length
不为零。
const array1 = [1, 2, 3, 4];
// Fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// Expected output: Array [1, 2, 0, 0]
// Fill with 5 from position 1
console.log(array1.fill(5, 1));
// Expected output: Array [1, 5, 5, 5]
console.log(array1.fill(6));
// Expected output: Array [6, 6, 6, 6]
Array.prototype.filter()
filter()
方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。
filter() 方法是一个迭代方法。它为数组中的每个元素调用提供的 callbackFn 函数一次,并构造一个由所有返回真值的元素值组成的新数组。未通过 callbackFn 测试的数组元素不会包含在新数组中。
callbackFn 仅对已分配值的数组索引调用。它不会对稀疏数组中的空槽调用。
filter() 方法是一个复制方法。它不会改变 this,而是返回一个包含与原始数组相同的元素(其中某些元素已被过滤掉)的浅拷贝。但是,作为 callbackFn 的函数可以更改数组。请注意,在第一次调用 callbackFn 之前,数组的长度已经被保存。因此:
-
当开始调用 filter() 时,callbackFn 将不会访问超出数组初始长度的任何元素。
-
对已访问索引的更改不会导致再次在这些元素上调用 callbackFn。
-
如果数组中一个现有的、尚未访问的元素被 callbackFn 更改,则它传递给 callbackFn 的值将是该元素被修改后的值。被删除的元素则不会被访问。
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
console.log(result);
// Expected output: Array ["exuberant", "destruction", "present"]
Array.prototype.find()
find()
方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined
。
- 如果需要在数组中找到对应元素的索引,请使用 findIndex()。
- 如果需要查找某个值的索引,请使用 Array.prototype.indexOf()。(它类似于 findIndex(),但只是检查每个元素是否与值相等,而不是使用测试函数。)
- 如果需要查找数组中是否存在某个值,请使用 Array.prototype.includes()。同样,它检查每个元素是否与值相等,而不是使用测试函数。
- 如果需要查找是否有元素满足所提供的测试函数,请使用 Array.prototype.some()。
find() 方法是一个迭代方法。它按索引升序顺序为数组中的每个元素调用提供的 callbackFn 函数,直到 callbackFn 返回一个真值。然后 find() 返回该元素并停止迭代数组。如果 callbackFn 从未返回真值,则 find() 返回 undefined。
callbackFn 被调用来处理数组的每一个索引,而不仅仅是那些有值的索引。在稀疏数组中,未赋值的空槽与 undefined 表现相同。
find() 不会改变被调用的数组,但是提供给 callbackFn 的函数可能会改变它。但需要注意的是,在第一次调用 callbackFn 之前,数组的长度会被保存。因此:
- 当调用 find() 时,callbackFn 不会访问超出数组初始长度的任何元素。
- 对已经访问过的索引的更改不会导致再次在这些元素上调用 callbackFn。
- 如果 callbackFn 改变了数组中已存在但尚未被访问的元素,则传递给 callbackFn 的该元素的值将是该元素在被访问时的值。被删除的元素被视为 undefined。
const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
console.log(found);
// Expected output: 12
Array.prototype.findIndex()
findIndex()
方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回 -1。
findIndex() 是一种迭代方法。它按照索引升序依次遍历数组中的每个元素,并调用提供的 callbackFn 函数,直到 callbackFn 返回一个真值。然后 findIndex() 返回该元素的索引并停止遍历数组。如果 callbackFn 从未返回一个真值,则 findIndex() 返回 -1。
callbackFn 被调用来处理数组的每一个索引,而不仅仅是那些有值的索引。在稀疏数组中,未赋值的空槽与 undefined 表现相同。
findIndex() 不会改变被调用的数组,但是提供给 callbackFn 的函数可能会改变它。但需要注意的是,在第一次调用 callbackFn 之前,数组的长度会被保存。因此:
- 当调用 findIndex() 时,callbackFn 不会访问超出数组初始长度的任何元素。
- 对已经访问过的索引的更改不会导致再次在这些元素上调用 callbackFn。
- 如果 callbackFn 改变了数组中已存在但尚未被访问的元素,则传递给 callbackFn 的该元素的值将是该元素在被访问时的值。被删除的元素被视为 undefined。
const array1 = [5, 12, 8, 130, 44];
const isLargeNumber = (element) => element > 13;
console.log(array1.findIndex(isLargeNumber));
// Expected output: 3
Array.prototype.findLast()
findLast()
方法反向迭代数组,并返回满足提供的测试函数的第一个元素的值。如果没有找到对应元素,则返回 undefined
。
如果你需要找到:
- 第一个匹配的元素,使用 find()。
- 数组中最后一个匹配元素的索引,使用 findLastIndex()。
- 某个值的索引,使用 indexOf()。(它类似于 findIndex(),但是会检查每个元素是否与值相等,而不是使用一个测试函数。)
- 该数组中是否存在一个值,使用 includes()。同样地,它检查每个元素是否和值相等,而不是使用一个测试函数。
- 是否有任意一个元素满足提供的测试函数,使用 some()。
findLast() 是一个迭代方法。该方法对数组每一个元素按降序(索引从大到小)执行 callbackFn 函数,直到 callbackFn 返回一个真值。然后 findLast() 返回该元素的值并停止遍历数组。如果 callbackFn 没有返回一个真值,则 findLast() 返回 undefined。
callbackFn 会被数组中的每个元素调用,而不仅仅是那些被赋值的元素。对于稀疏数组来说,空槽行为和 undefined 相同。
findLast() 方法不会改变调用它的数组,但是提供的 callbackFn 可以。但是请注意,数组的长度是在第一次调用 callbackFn 之前保存的。因此:
- callbackFn 不会访问在调用 findLast() 开始后才添加到数组中的任何元素。
- 给已访问过的索引重新赋值将不会被 callbackFn 重新访问。
- 如果 callbackFn 更改了数组中现有的、尚未访问的元素,则其传递给 callbackFn 的值将是 findLast() 访问该元素索引时的值。已删除的元素会被当做 undefined 来访问。
const array1 = [5, 12, 50, 130, 44];
const found = array1.findLast((element) => element > 45);
console.log(found);
// Expected output: 130
Array.prototype.findLastIndex()
findLastIndex()
方法反向迭代数组,并返回满足所提供的测试函数的第一个元素的索引。若没有找到对应元素,则返回 -1。
findLastIndex() 方法是一个迭代方法。它为数组中的每个元素按索引降序调用一次提供的 callbackFn 函数,直到 callbackFn 返回一个真值。然后 findLastIndex() 返回元素的索引并且停止遍历数组。如果 callbackFn 没有返回一个真值,则 findLastIndex() 返回 -1。
callbackFn 会为数组中的每个元素调用,而不仅仅是那些被赋值的元素,这意味着对于稀疏数组来说,空槽的行为和 undefined 相同。
findLastIndex() 方法不会改变调用它的数组,但是提供的 callbackFn 可以。但是请注意,数组的长度是在第一次调用 callbackFn 之前保存的。因此:
- callbackFn 不会访问在调用 findLastIndex() 开始后才添加到数组中的任何元素。
- 对已访问索引的更改不会导致对它们再次调用 callbackFn 函数。
- 如果 callbackFn 更改了数组中现有的、尚未访问的元素,它传递给callbackFn 的值将是该元素被访问时的值。已删除元素被当作 undefined 来访问。
const array1 = [5, 12, 50, 130, 44];
const isLargeNumber = (element) => element > 45;
console.log(array1.findLastIndex(isLargeNumber));
// Expected output: 3
// Index of element with value: 130
Array.prototype.flat()
flat()
方法创建一个新的数组,并根据指定深度递归地将所有子数组元素拼接到新的数组中。
flat() 方法属于复制方法。它不会改变 this 数组,而是返回一个浅拷贝,该浅拷贝包含了原始数组中相同的元素。
如果待展开的数组是稀疏的,flat() 方法会忽略其中的空槽。例如,如果 depth 是 1,那么根数组和第一层嵌套数组中的空槽都会被忽略,但在更深的嵌套数组中的空槽则会与这些数组一起保留。
flat() 方法是通用的。它只需要 this 值具有 length 属性和整数键属性即可。但是,如果要展开元素,则它们必须是数组。
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// Expected output: Array [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat(2));
// Expected output: Array [0, 1, 2, Array [3, 4]]
Array.prototype.flatMap()
flatMap()
方法对数组中的每个元素应用给定的回调函数,然后将结果展开一级,返回一个新数组。它等价于在调用 map()
方法后再调用深度为 1 的 flat()
方法(arr.map(...args).flat()
),但比分别调用这两个方法稍微更高效一些。
flatMap() 方法是一个迭代方法。有关回调函数的详细说明,请参见 Array.prototype.map()。flatMap() 方法等同于调用 map(callbackFn, thisArg) 后再调用 flat(1)——对于每个元素,它都会生成一个新元素数组,并将生成的数组连接起来形成一个新数组。
flatMap() 方法是通用的。它只需要 this 值具有 length 属性和整数键属性即可。但是,如果要展开从回调函数 callbackFn 返回的值,则该值必须是数组。
const arr1 = [1, 2, 1];
const result = arr1.flatMap((num) => (num === 2 ? [2, 2] : 1));
console.log(result);
// Expected output: Array [1, 2, 2, 1]
Array.prototype.forEach()
forEach()
方法对数组的每个元素执行一次给定的函数。
forEach() 方法是一个迭代方法。它按索引升序地为数组中的每个元素调用一次提供的 callbackFn 函数。与 map() 不同,forEach() 总是返回 undefined,而且不能继续链式调用。其典型的用法是在链式调用的末尾执行某些操作。
callbackFn 仅对已赋值的数组索引调用。对于稀疏数组中的空槽,它不会被调用。
forEach() 不会改变其调用的数组,但是,作为 callbackFn 的函数可以更改数组。请注意,在第一次调用 callbackFn 之前,数组的长度已经被保存。因此:
- 当调用 forEach() 时,callbackFn 不会访问超出数组初始长度的任何元素。
- 已经访问过的索引的更改不会导致 callbackFn 再次调用它们。
- 如果 callbackFn 更改了数组中已经存在但尚未访问的元素,则传递给 callbackFn 的值将是在访问该元素时的值。已经被删除的元素不会被访问。
const array1 = ['a', 'b', 'c'];
array1.forEach(element => console.log(element));
// Expected output: "a"
// Expected output: "b"
// Expected output: "c"
Array.from()
Array.from()
静态方法从可迭代或类数组对象创建一个新的浅拷贝的数组实例。
转换异步的可迭代对象到数组,可以使用 Array.fromAsync()
。
Array.from() 可以通过以下方式来创建数组对象:
-
可迭代对象(例如 Map 和 Set 对象);或者,如果对象是不可迭代的,
-
类数组对象(带有 length 属性和索引元素的对象)。
Array.from() 绝不会创建稀疏数组。如果 arrayLike 对象缺少一些索引属性,那么这些属性在新数组中将是 undefined。
Array.from() 有一个可选的参数 mapFn,该参数允许你在创建数组时为每个元素执行一个函数,类似于 map()。更明确地说,Array.from(obj, mapFn, thisArg) 和 Array.from(obj).map(mapFn, thisArg) 具有相同的结果,只是它不会创建中间数组,并且 mapFn 仅接受两个参数(element、index),不接受数组,因为数组仍然在构建中。
console.log(Array.from('foo'));
// Expected output: Array ["f", "o", "o"]
console.log(Array.from([1, 2, 3], x => x + x));
// Expected output: Array [2, 4, 6]
Array.prototype.includes()
includes()
方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true
,否则返回 false
。
includes() 方法使用零值相等算法将 searchElement 与数组中的元素进行比较。0 值都被认为是相等的,不管符号是什么。(即 -0 等于 0),但 false 不被认为与 0 相同。NaN 可以被正确搜索到。
当在稀疏数组上使用时, includes() 方法迭代空槽,就像它们的值是 undefined 一样。
includes() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
const array1 = [1, 2, 3];
console.log(array1.includes(2));
// Expected output: true
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
// Expected output: true
console.log(pets.includes('at'));
// Expected output: false
Array.prototype.indexOf()
indexOf()
方法返回数组中第一次出现给定元素的下标,如果不存在则返回 -1。
indexOf() 使用严格相等(与 === 运算符使用的算法相同)将 searchElement 与数组中的元素进行比较。NaN 值永远不会被比较为相等,因此当 searchElement 为 NaN 时 indexOf() 总是返回 -1。
indexOf() 方法会跳过稀疏数组中的空槽。
indexOf() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
console.log(beasts.indexOf('bison'));
// Expected output: 1
// Start from index 2
console.log(beasts.indexOf('bison', 2));
// Expected output: 4
console.log(beasts.indexOf('giraffe'));
// Expected output: -1
Array.isArray()
Array.isArray()
静态方法用于确定传递的值是否是一个 Array
。
Array.isArray() 检查传递的值是否为 Array。它不检查值的原型链,也不依赖于它所附加的 Array 构造函数。对于使用数组字面量语法或 Array 构造函数创建的任何值,它都会返回 true。这使得它可以安全地使用跨领域(cross-realm)对象,其中 Array 构造函数的标识是不同的,因此会导致 instanceof Array 失败。
Array.isarray() 也拒绝原型链中带有 Array.prototype,而实际不是数组的对象,但 instanceof Array 会接受。
console.log(Array.isArray([1, 3, 5]));
// Expected output: true
console.log(Array.isArray('[]'));
// Expected output: false
console.log(Array.isArray(new Array(5)));
// Expected output: true
console.log(Array.isArray(new Int16Array([15, 33])));
// Expected output: false
Array.prototype.join()
join()
方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串,用逗号或指定的分隔符字符串分隔。如果数组只有一个元素,那么将返回该元素而不使用分隔符。
所有数组元素被转换成字符串并连接到一个字符串中。如果一个元素是 undefined 或 null,它将被转换为空字符串,而不是字符串 “undefined” 或 “null”。
Array.prototype.toString() 会在内部访问 join 方法,不带参数。覆盖一个数组实例的 join 也将覆盖它的 toString 行为。
当在稀疏数组上使用时,join() 方法迭代空槽,就像它们的值为 undefined 一样。
join() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
const elements = ['Fire', 'Air', 'Water'];
console.log(elements.join());
// Expected output: "Fire,Air,Water"
console.log(elements.join(''));
// Expected output: "FireAirWater"
console.log(elements.join('-'));
// Expected output: "Fire-Air-Water"
Array.prototype.keys()
keys()
方法返回一个新的数组迭代器对象,其中包含数组中每个索引的键。
当用于稀疏数组时,keys() 方法迭代空槽,就像它们的值 undefined 一样。
keys() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
const array1 = ['a', 'b', 'c'];
const iterator = array1.keys();
for (const key of iterator) {
console.log(key);
}
// Expected output: 0
// Expected output: 1
// Expected output: 2
Array.prototype.lastIndexOf()
lastIndexOf()
方法返回数组中给定元素最后一次出现的索引,如果不存在则返回 -1。该方法从 fromIndex
开始向前搜索数组。
lastIndexOf 使用严格相等(与 === 运算符使用的算法相同)比较 searchElement 和数组中的元素。NaN 值永远不会被比较为相等,因此当 searchElement 为 NaN 时 lastIndexOf() 总是返回 -1。
lastIndexOf() 方法会跳过稀疏数组中的空槽。
lastIndexOf() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];
console.log(animals.lastIndexOf('Dodo'));
// Expected output: 3
console.log(animals.lastIndexOf('Tiger'));
// Expected output: 1
Array.prototype.map()
map()
方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。
map() 方法是一个迭代方法。它为数组中的每个元素调用一次提供的 callbackFn 函数,并用结果构建一个新数组。
callbackFn 仅在已分配值的数组索引处被调用。它不会在稀疏数组中的空槽处被调用。
map() 方法是一个复制方法。它不会改变 this。然而,作为 callbackFn 提供的函数可以更改数组。请注意,在第一次调用 callbackFn 之前,数组的长度已经被保存。因此:
- 当开始调用 map() 时,callbackFn 将不会访问超出数组初始长度的任何元素。
- 对已访问索引的更改不会导致再次在这些元素上调用 callbackFn。
- 如果数组中一个现有的、尚未访问的元素被 callbackFn 更改,则它传递给 callbackFn 的值将是该元素被修改后的值。被删除的元素则不会被访问。
map() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
由于 map 创建一个新数组,在没有使用返回的数组的情况下调用它是不恰当的;应该使用 forEach 或 for…of 作为代替。
const array1 = [1, 4, 9, 16];
// Pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// Expected output: Array [2, 8, 18, 32]
Array.of()
Array.of()
方法通过可变数量的参数创建一个新的 Array
实例,而不考虑参数的数量或类型。
Array.of() 和 Array() 构造函数之间的区别在于对单个参数的处理:Array.of(7) 创建一个具有单个元素 7 的数组,而 Array(7) 创建一个 length 为 7 的空数组(这意味着一个由 7 个空槽组成的数组,而不是具有实际 undefined 值的槽)。
Array.of(1); // [1]
Array.of(1, 2, 3); // [1, 2, 3]
Array.of(undefined); // [undefined]
Array.prototype.pop()
pop()
方法从数组中删除最后一个元素,并返回该元素的值。此方法会更改数组的长度。
pop() 方法从一个数组中删除并返回最后一个元素给调用者。如果你在空数组上调用 pop(),它会返回 undefined。
Array.prototype.shift() 和 pop() 有类似的行为,但是它是作用在数组的第一个元素上的。
pop() 是修改方法。其改变了 this 的长度和内容。如果你想要 this 不变,但是返回一个新的最后一个元素被移除的数组,你可以使用 arr.slice(0, -1) 来代替。
pop() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。虽然字符串也是类数组对象,但是由于其不能被修改,所以 pop() 方法并不能应用在字符串上。
const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];
console.log(plants.pop());
// Expected output: "tomato"
console.log(plants);
// Expected output: Array ["broccoli", "cauliflower", "cabbage", "kale"]
plants.pop();
console.log(plants);
// Expected output: Array ["broccoli", "cauliflower", "cabbage"]
Array.prototype.push()
push()
方法将指定的元素添加到数组的末尾,并返回新的数组长度。
push() 方法将值追加到一个数组中。
Array.prototype.unshift() 有着和 push() 相似的行为,但是其作用于数组的开头。
push() 方法是一个修改方法。它改变了 this 的内容和长度。如果你希望 this 的值保持不变,但返回一个末尾追加了元素的新数组,你可以使用 arr.concat([element0, element1, /* … ,*/ elementN]) 来代替。请注意,这些元素需要被包装在一个额外的数组中——否则,如果元素本身是一个数组,由于 concat() 的行为,它将被展开而不是作为单个元素添加到原数组的末尾。
push() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。虽然字符串也是类似数组的,但这个方法不适用于它,因为字符串是不可变的。
const animals = ['pigs', 'goats', 'sheep'];
const count = animals.push('cows');
console.log(count);
// Expected output: 4
console.log(animals);
// Expected output: Array ["pigs", "goats", "sheep", "cows"]
animals.push('chickens', 'cats', 'dogs');
console.log(animals);
// Expected output: Array ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"]
Array.prototype.reduce()
reduce()
方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)。
下面的例子能够帮助你理解 reduce()
的用处——计算数组所有元素的总和:
const array1 = [1, 2, 3, 4];
// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
(accumulator, currentValue) => accumulator + currentValue,
initialValue
);
console.log(sumWithInitial);
// Expected output: 10
Array.prototype.reduceRight()
reduceRight()
方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。
reduceRight 为数组中每个元素调用一次 callback 回调函数,但是数组中被删除的索引或从未被赋值的索引会跳过。回调函数接受四个参数:初始值(或上次调用回调的返回值)、当前元素值、当前索引,以及调用迭代的当前数组。
const array1 = [[0, 1], [2, 3], [4, 5]];
const result = array1.reduceRight((accumulator, currentValue) => accumulator.concat(currentValue));
console.log(result);
// Expected output: Array [4, 5, 2, 3, 0, 1]
Array.prototype.reverse()
reverse()
方法将就地反转数组中的元素,并返回同一数组的引用。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。换句话说,数组中的元素顺序将转向与之前固定方向相反的方向。
reverse 方法反转数组中元素的位置,改变了数组,并返回该数组的引用。
reverse() 方法会保留空槽。如果源数组是稀疏的,则空槽对应的新索引将被删除,并且也成为空槽。
reverse() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。虽然字符串也是类似于数组的,但这个方法不适用于它们,因为字符串是不可变的。
const array1 = ['one', 'two', 'three'];
console.log('array1:', array1);
// Expected output: "array1:" Array ["one", "two", "three"]
const reversed = array1.reverse();
console.log('reversed:', reversed);
// Expected output: "reversed:" Array ["three", "two", "one"]
// Careful: reverse is destructive -- it changes the original array.
console.log('array1:', array1);
// Expected output: "array1:" Array ["three", "two", "one"]
Array.prototype.shift()
shift()
方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
shift 方法移除索引为 0 的元素,并将后续元素的下标依次向前移动,然后返回被移除的元素。如果 length 属性的值为 0,则返回 undefined。
pop() 方法有着和 shift() 相似的行为。但是是作用于数组的最后一个元素上的。
shift() 方法是一个改变方法。它改变了 this 的内容和长度。如果你希望保持 this 的值不变,但返回一个删除了第一个元素的新数组,你可以使用 arr.slice(1)。
shift() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。虽然字符串也是类似数组的,但这个方法不适合应用于它们,因为字符串是不可变的。
const array1 = [1, 2, 3];
const firstElement = array1.shift();
console.log(array1);
// Expected output: Array [2, 3]
console.log(firstElement);
// Expected output: 1
Array.prototype.slice()
slice()
方法返回一个新的数组对象,这一对象是一个由 start
和 end
决定的原数组的浅拷贝(包括 start
,不包括 end
),其中 start
和 end
代表了数组元素的索引。原始数组不会被改变。
slice() 方法是一个复制方法。它不会改变 this,而是返回一个浅拷贝,其中包含了原始数组的一部分相同的元素。
slice() 方法会保留空槽。如果被切片的部分是稀疏的,则返回的数组也是稀疏的。
slice() 方法是通用的。它只要求 this 上有 length 属性和整数键属性。
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slice(2));
// Expected output: Array ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4));
// Expected output: Array ["camel", "duck"]
console.log(animals.slice(1, 5));
// Expected output: Array ["bison", "camel", "duck", "elephant"]
console.log(animals.slice(-2));
// Expected output: Array ["duck", "elephant"]
console.log(animals.slice(2, -1));
// Expected output: Array ["camel", "duck"]
console.log(animals.slice());
// Expected output: Array ["ant", "bison", "camel", "duck", "elephant"]
Array.prototype.some()
some()
方法测试数组中是否至少有一个元素通过了由提供的函数实现的测试。如果在数组中找到一个元素使得提供的函数返回 true,则返回 true;否则返回 false。它不会修改数组。
some() 方法是一个迭代方法。它为数组中的每个元素调用一次指定的 callbackFn 函数,直到 callbackFn 返回一个真值。如果找到这样的元素,some() 方法将会立即返回 true 并停止遍历数组。否则,如果 callbackFn 对所有元素都返回假值,some() 就会返回 false。
some() 类似于数学中的“存在量词(∃)”。特别地,在对于一个空数组,任何条件下它都返回 false。
callbackFn 仅针对已分配值的数组索引调用。它不会为稀疏数组中的空槽调用。
some() 不会改变调用它的数组,但指定的 callbackFn 函数可以。但是请注意,数组的长度是在第一次调用 callbackFn 之前保存的。因此:
- 当开始调用 some() 时,callbackFn 将不会访问超出数组初始长度的任何元素。
- 对已访问索引的更改不会导致再次在这些元素上调用 callbackFn。
- 如果数组中一个现有的、尚未访问的元素被 callbackFn 更改,则它传递给 callbackFn 的值将是该元素被修改后的值。被删除的元素则不会被访问。
const array = [1, 2, 3, 4, 5];
// Checks whether an element is even
const even = (element) => element % 2 === 0;
console.log(array.some(even));
// Expected output: true
Array.prototype.sort()
sort()
方法原地对数组的元素进行排序,并返回相同数组的引用。默认排序顺序是升序,将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列。
由于它取决于具体实现,因此无法保证排序的时间和空间复杂度。
如果没有提供 compareFn,所有非 undefined 的数组元素都会被转换为字符串,并按照 UTF-16 码点顺序比较字符串进行排序。例如“banana”会被排列到“cherry”之前。在数值排序中,9 出现在 80 之前,但因为数字会被转换为字符串,在 Unicode 顺序中“80”要比“9”要靠前。所有的 undefined 元素都会被排序到数组的末尾。
sort() 方法保留空槽。如果源数组是稀疏的,则空槽会被移动到数组的末尾,并始终排在所有 undefined 元素的后面。
const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// Expected output: Array ["Dec", "Feb", "Jan", "March"]
const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// Expected output: Array [1, 100000, 21, 30, 4]
Array.prototype.splice()
splice()
方法原地改变一个数组的内容,通过移除或者替代已存在的元素和/或添加新元素。
splice() 方法是一个修改方法。它可能会更改 this 的内容。如果指定的要插入的元素数量与要删除的元素数量不同,数组的 length 也将会更改。同时,它会使用 @@species 来创建一个空数组实例并返回。
如果删除的部分是稀疏的,则 splice() 返回的数组也是稀疏的,对应的索引为空槽。
splice() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。尽管字符串也类似于数组,但这种方法不适用于它,因为字符串是不可变的。
const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// Inserts at index 1
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "June"]
months.splice(4, 1, 'May');
// Replaces 1 element at index 4
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "May"]
Array.prototype.toLocaleString()
toLocaleString()
方法返回一个字符串,表示数组中的所有元素。每个元素通过调用它们自己的 toLocaleString
方法转换为字符串,并且使用特定于语言环境的字符串(例如逗号“,”)分隔开。
Array.prototype.toLocaleString 方法遍历数组内容,并使用提供的 locales 和 options 参数调用每个元素的 toLocaleString 方法,通过由实现定义的分隔符(例如逗号“,”)将转换后的字符串拼接起来。请注意,该方法本身不会使用这两个参数——它只是将其传递给每个元素的 toLocaleString()。分隔符的选择取决于主机当前的语言环境,而不是 locales 参数。
如果一个元素是 undefined、null,它会被转换为空字符串,而不是 “null” 或者 “undefined”。
当用于稀疏数组时,toLocaleString() 方法会把空槽当作 undefined 值一样迭代它。
toLocaleString() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
const array1 = [1, 'a', new Date('21 Dec 1997 14:12:00 UTC')];
const localeString = array1.toLocaleString('en', { timeZone: 'UTC' });
console.log(localeString);
// Expected output: "1,a,12/21/1997, 2:12:00 PM",
// This assumes "en" locale and UTC timezone - your results may vary
Array.prototype.toReversed()
Array
实例的 toReversed()
方法是 reverse()
方法对应的复制版本。它返回一个元素顺序相反的新数组。
toReversed() 方法将调用该方法的数组对象的元素以相反的顺序调换,并返回一个新数组。
当用于稀疏数组时,toReversed() 方法迭代空槽,就像它们的值是 undefined 一样。
toReversed() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
const items = [1, 2, 3];
console.log(items); // [1, 2, 3]
const reversedItems = items.toReversed();
console.log(reversedItems); // [3, 2, 1]
console.log(items); // [1, 2, 3]
Array.prototype.toSorted()
Array
实例的 toSorted()
方法是 sort()
方法的复制方法版本。它返回一个新数组,其元素按升序排列。
有关 compareFn 参数的更多信息,请参阅 sort()。
当在稀疏数组上使用 toSorted() 方法时,它迭代时会将空槽视为具有 undefined 值的元素。
toSorted() 方法是通用的,它只期望 this 值具有 length 属性和整数键属性。
const months = ["Mar", "Jan", "Feb", "Dec"];
const sortedMonths = months.toSorted();
console.log(sortedMonths); // ['Dec', 'Feb', 'Jan', 'Mar']
console.log(months); // ['Mar', 'Jan', 'Feb', 'Dec']
const values = [1, 10, 21, 2];
const sortedValues = values.toSorted((a, b) => a - b));
console.log(sortedValues); // [1, 2, 10, 21]
console.log(values); // [1, 10, 21, 2]
Array.prototype.toSpliced()
Array
实例的 toSpliced()
方法是 splice()
方法的复制版本。它返回一个新数组,并在给定的索引处删除和/或替换了一些元素。
toSpliced() 方法与 splice() 类似,可以同时完成多个操作:在数组中给定的索引开始移除指定数量的元素,然后在相同的索引处插入给定的元素。但是,它返回一个新数组,而不是修改原始数组。因此,此方法不会返回已删除的元素。
toSpliced() 方法不会产生稀疏数组。如果原始数组是稀疏的,在新数组中空槽将会被替换成 undefined。
toSpliced() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
const months = ["Jan", "Mar", "Apr", "May"];
// 在索引 1 处添加一个元素
const months2 = months.toSpliced(1, 0, "Feb");
console.log(months2); // ["Jan", "Feb", "Mar", "Apr", "May"]
// 从第 2 个索引开始删除两个元素
const months3 = months2.toSpliced(2, 2);
console.log(months3); // ["Jan", "Feb", "May"]
// 在索引 1 处用两个新元素替换一个元素
const months4 = months3.toSpliced(1, 1, "Feb", "Mar");
console.log(months4); // ["Jan", "Feb", "Mar", "May"]
// 原数组不会被修改
console.log(months); // ["Jan", "Mar", "Apr", "May"]
Array.prototype.toString()
toString()
方法返回一个字符串,表示指定的数组及其元素。
Array 对象覆盖了 Object 的 toString 方法。数组的 toString 方法实际上在内部调用了 join() 方法来拼接数组并返回一个包含所有数组元素的字符串,元素之间用逗号分隔。如果 join 方法不可用或者不是函数,则会使用 Object.prototype.toString 来代替, 并返回 [object Array]。
const array1 = [1, 2, 'a', '1a'];
console.log(array1.toString());
// Expected output: "1,2,a,1a"
Array.prototype.unshift()
unshift()
方法将指定元素添加到数组的开头,并返回数组的新长度。
unshift() 方法将给定的值插入到类数组对象的开头。
Array.prototype.push() 有着和 unshift() 相似的行为,但是其将元素插入到数组的末尾。
请注意,如果多个元素作为参数传递,它们将被插入到对象开头的块中,与它们作为参数传递的顺序完全相同。因此,调用一次 unshift() 方法并传递 n 个参数,与调用 n 次并传递 1 个参数(例如使用循环),不会产生相同的结果。
const array1 = [1, 2, 3];
console.log(array1.unshift(4, 5));
// Expected output: 5
console.log(array1);
// Expected output: Array [4, 5, 1, 2, 3]
Array.prototype.values()
values()
方法返回一个新的数组迭代器对象,该对象迭代数组中每个元素的值。
const array1 = ['a', 'b', 'c'];
const iterator = array1.values();
for (const value of iterator) {
console.log(value);
}
// Expected output: "a"
// Expected output: "b"
// Expected output: "c"
Array.prototype.with()
Array
实例的 with()
方法是使用方括号表示法修改指定索引值的复制方法版本。它会返回一个新数组,其指定索引处的值会被新值替换。
with() 通过返回一个指定索引处的值被新值替换的新数组,来改变数组中指定索引处的值。原数组不会被修改。这使得你可以以链式调用数组方法的方式来对数组进行操作。
with() 方法永远不会产生稀疏数组。如果原数组是稀疏的,新数组对应的空白索引位置会替换为 undefined。
with() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。
const arr = [1, 2, 3, 4, 5];
console.log(arr.with(2, 6)); // [1, 2, 6, 4, 5]
console.log(arr); // [1, 2, 3, 4, 5]