JavaScript常用数组方法汇总

68 阅读15分钟

前言

使用JavaScript的小伙伴都知道,数组(Array)在日常开发中的使用是非常频繁的,但是经常性用到的数组方法也就那几个,为了更全面地掌握数组的使用,本文为大家总结了以下JavaScript中数组常用方法,让你玩转数组无压力,请往下看

Array.prototype.forEach()

forEach()  方法对数组的每个元素执行一次对应的操作

const arr1 = ['a', 'b', 'c'];
arr1.forEach(element => console.log(element));
// a
// b
// c

注意:forEach()遍历的元素是只读的,不能改变其元素的值,但是可以改变复杂类型的属性值,回调函数传入的参数类似是const声明的

const arr1 = ['a', 'b', 'c'];
arr1.forEach(element => element = element + '1')
console.log(arr1) // [ 'a', 'b', 'c' ]

const arr2 = [
    { k: 'a' },
    { k: 'b' },
    { k: 'b' }
]
arr2.forEach(element=> element.k=element.k+'1')
console.log(arr2)  // [ { k: 'a1' }, { k: 'b1' }, { k: 'b1' } ]

Array.prototype.map()

map()  方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

const arr = [1, 4, 9, 16];

const map1 = arr.map(x => x * 2);
console.log(map1); // [ 2, 8, 18, 32 ]

Array.prototype.filter()

filter()  方法创建给定数组一部分的浅拷贝,其包含回调函数返回值为true的所有元素。

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);  //  [ 'exuberant', 'destruction', 'present' ]

Array.prototype.concat()

concat() 方法创建一个新的数组,它由被调用的对象中的元素组成,每个参数的顺序依次是该参数的元素(如果参数是数组)或参数本身(如果参数不是数组)。它不会递归到嵌套数组参数中。

concat() 方法不会改变 this 或任何作为参数提供的数组,而是返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。原始数组的元素将复制到新数组中,如下所示:

  • 对象引用(而不是实际对象):concat 将对象引用复制到新数组中。原始数组和新数组都引用相同的对象。也就是说,如果引用的对象被修改,则更改对于新数组和原始数组都是可见的。这包括也是数组的数组参数的元素。
  • 数据类型如字符串,数字和布尔(不是 StringNumber 和 Boolean 对象):concat 将字符串和数字的值复制到新数组中。
const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);

console.log(array3);  // ["a", "b", "c", "d", "e", "f"]

Array.prototype.slice()

slice()  方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。

const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2));  // Array ["camel", "duck", "elephant"]

console.log(animals.slice(2, 4));  // Array ["camel", "duck"]

console.log(animals.slice(1, 5));  // Array ["bison", "camel", "duck", "elephant"]

console.log(animals.slice(-2));  // Array ["duck", "elephant"]

console.log(animals.slice(2, -1));  // Array ["camel", "duck"]

console.log(animals.slice());  // Array ["ant", "bison", "camel", "duck", "elephant"]

Array.prototype.push()

push()  方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。

const animals = ['pigs', 'goats', 'sheep'];

const count = animals.push('cows');
console.log(count);  // 4
console.log(animals);  // Array ["pigs", "goats", "sheep", "cows"]

animals.push('chickens', 'cats', 'dogs');
console.log(animals);  // Array ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"]

Array.prototype.pop()

pop()  方法从数组中删除最后一个元素,并返回该元素的值。此方法会更改数组的长度。

const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];

console.log(plants.pop());   // "tomato"

console.log(plants);   // Array ["broccoli", "cauliflower", "cabbage", "kale"]

plants.pop();

console.log(plants);   // Array ["broccoli", "cauliflower", "cabbage"]

Array.prototype.unshift()

unshift()  方法将一个或多个元素添加到数组的开头,并返回该数组的新长度

const array1 = [1, 2, 3];

console.log(array1.unshift(4, 5));  // 5

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

Array.prototype.shift()

shift()  方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

const array1 = [1, 2, 3];

const firstElement = array1.shift();

console.log(array1);  // Array [2, 3]

console.log(firstElement);  // 1

Array.prototype.some()

some()  方法检查数组中是不是至少有 1 个元素通过了被提供的函数测试。它返回的是一个 Boolean 类型的值

备注:  如果用一个空数组进行测试,在任何情况下它返回的都是false

some() 为数组中的每一个元素执行一次 callback 函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some() 将会立即返回 true。否则,some() 返回 falsecallback 只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。

const array = [1, 2, 3, 4, 5];

const c1 = (element) => element % 2 === 0;
const c2 = (element) => element % 6 === 0;

console.log(array.some(c1)); // true
console.log(array.some(c2)); // false

Array.prototype.every()

every()  方法检查一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。

every 方法为数组中的每个元素执行一次 callback 函数,直到它找到一个会使 callback 返回 false 的元素。如果发现了一个这样的元素,every 方法将会立即返回 false。否则,callback 为每一个元素返回 trueevery 就会返回 truecallback 只会为那些已经被赋值的索引调用。不会为那些被删除或从未被赋值的索引调用。

const array1 = [1, 30, 39, 29, 10, 13];

const c1 = (currentValue) => currentValue < 20;
const c2 = (currentValue) => currentValue > 0;

console.log(array1.every(c1));   // false
console.log(array1.every(c2));   // true

Array.prototype.fill()

fill()  方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

注意:   如果填充值是引用类型,会将改引用值填充到对应的元素中,即是浅拷贝,这个时候改变数组任意一个元素的属性值,其他的元素属性也会同步改变。

参数

  • value

    用来填充数组元素的值。

  • start 可选

    起始索引,默认值为 0。

  • end 可选

    终止索引,默认值为 arr.length

const array1 = [1, 2, 3, 4];

console.log(array1.fill(0, 2, 4));  //  [1, 2, 0, 0]

console.log(array1.fill(5, 1));  //  [1, 5, 5, 5]

console.log(array1.fill(6));  //  [6, 6, 6, 6]

Array.prototype.at()

at()  方法接收一个整数值并返回该索引的项目,允许正数和负数。负整数从数组中的最后一个项目开始倒数。

这不代表使用方括号符号有什么问题。例如,array[0] 将返回第一个项目。然而,对于后面的元素的读取,你需要用到 array.length,例如,读取最后一个元素,你需要使用 array[array-1],对比以上方法读取最后一个项目,你可以调用 array.at(-1)

const array1 = [5, 12, 8, 130, 44];

let index = 2;

console.log(`Using an index of ${index} the item returned is ${array1.at(index)}`);
//  "Using an index of 2 the item returned is 8"

index = -2;

console.log(`Using an index of ${index} item returned is ${array1.at(index)}`);
//  "Using an index of -2 item returned is 130"

Array.prototype.sort()

sort()  方法对数组的元素进行就地排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列时构建的

由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。

参数

  • compareFn 可选

    用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的 Unicode 位点进行排序。

    • a

      第一个用于比较的元素。

    • b

      第二个用于比较的元素。

如果没有指明 compareFn ,那么元素会按照转换为的字符串的诸个字符的 Unicode 位点进行排序。例如 "Banana" 会被排列到 "cherry" 之前。当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFn),比较的数字会先被转换为字符串,所以在 Unicode 顺序上 "80" 要比 "9" 要靠前。

如果指明了 compareFn ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:

  • 如果 compareFn(a, b) 大于 0,b 会被排列到 a 之前。
  • 如果 compareFn(a, b) 小于 0,那么 a 会被排列到 b 之前;
  • 如果 compareFn(a, b) 等于 0,a 和 b 的相对位置不变。备注:ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
  • compareFn(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。
const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);   // Array ["Dec", "Feb", "Jan", "March"]

const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);   // Array [1, 100000, 21, 30, 4]

const array2 = [1, 30, 4, 21, 100000];
array2.sort((a, b) => a-b)
console.log(array2)    // [ 1, 4, 21, 30, 100000 ]

Array.prototype.splice()

splice()  方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

splice() 方法返回值是由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。

参数

  • start​

    指定修改的开始位置(从 0 计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从 -1 计数,这意味着 -n 是倒数第 n 个元素并且等价于 array.length-n);如果负数的绝对值大于数组的长度,则表示开始位置为第 0 位。

  • deleteCount 可选

    整数,表示要移除的数组元素的个数。如果 deleteCount 大于 start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。如果 deleteCount 被省略了,或者它的值大于等于array.length - start(也就是说,如果它大于或者等于start之后的所有元素的数量),那么start之后数组的所有元素都会被删除。如果 deleteCount 是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。

  • item1, item2, ... 可选

    要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。

const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');

console.log(months);  // Array ["Jan", "Feb", "March", "April", "June"]

months.splice(4, 1, 'May');

console.log(months);  // Array ["Jan", "Feb", "March", "April", "May"]

months.splice(2,3)

console.log(months)   // Array ["Jan", "Feb"]

Array.prototype.reverse()

reverse()  方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。

const array1 = ['one', 'two', 'three'];
console.log('array1:', array1);    // "array1:" Array ["one", "two", "three"]

const reversed = array1.reverse();
console.log('reversed:', reversed);    // "reversed:" Array ["three", "two", "one"]

console.log('array1:', array1);    // "array1:" Array ["three", "two", "one"]

Array.prototype.join()

join()  方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个元素,那么将返回该项目而不使用分隔符。

参数

  • separator 可选

    指定一个字符串来分隔数组的每个元素。如果需要,将分隔符转换为字符串。如果缺省该值,数组元素用逗号(,)分隔。如果separator是空字符串 (""),则所有元素之间都没有任何字符。

注意:  如果一个元素为 undefined 或 null,它会被转换为空字符串。

const elements = ['Fire', 'Air', 'Water'];

console.log(elements.join());  // "Fire,Air,Water"

console.log(elements.join(''));  // "FireAirWater"

console.log(elements.join('-'));  // "Fire-Air-Water"

Array.prototype.indexOf()

indexOf()  方法返回在数组中可以找到给定元素的第一个索引,如果不存在,则返回 -1。

参数

  • searchElement

    要查找的元素。

  • fromIndex 可选

    开始查找的位置。如果该索引值大于或等于数组长度,意味着不会在数组里查找,返回 -1。如果参数中提供的索引值是一个负值,则将其作为数组末尾的一个抵消,即 -1 表示从最后一个元素开始查找,-2 表示从倒数第二个元素开始查找,以此类推。注意:如果参数中提供的索引值是一个负值,并不改变其查找顺序,查找顺序仍然是从前向后查询数组。如果抵消后的索引值仍小于 0,则整个数组都将会被查询。其默认值为 0。

备注: indexOf 使用全等运算(与 ===,或称为三等号运算符的方法相同)判断 searchElement 与数组中包含的元素之间的关系。

const beasts = ['ant', 'bison', 'camel', 'duck', 'bison',NaN];

console.log(beasts.indexOf('bison'));   // 1

console.log(beasts.indexOf('bison', 2));   // 4

console.log(beasts.indexOf('giraffe'));   // -1

console.log(beasts.indexOf(NaN));   // -1

Array.prototype.lastIndexOf()

lastIndexOf()  方法类似 indexOf() ,返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。

const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];

console.log(animals.lastIndexOf('Dodo'));   // 3

console.log(animals.lastIndexOf('Tiger'));  // 1

Array.prototype.includes()

includes()  方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false

参数

  • valueToFind

    需要查找的元素值。

    备注:  使用 includes() 比较字符串和字符时是区分大小写的。

  • fromIndex 可选

    fromIndex 索引处开始查找 valueToFind。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜(即使从末尾开始往前跳 fromIndex 的绝对值个索引,然后往后搜寻)。默认为 0。

备注:  技术上来讲,includes() 使用 零值相等 算法来确定是否找到给定的元素。

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true

Array.prototype.find()

find()  方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined

find 方法对数组中的每一项元素执行一次 callbackFn 函数,直至有一个 callbackFn 返回 true。当找到了这样一个元素后,该方法会立即返回这个元素的值,否则返回 undefined。注意 callbackFn 函数会为数组中的每个索引调用即从 0 到 length - 1,而不仅仅是那些被赋值的索引,这意味着对于稀疏数组来说,该方法的效率要低于那些只遍历有值的索引的方法。find 方法不会改变数组。

const array1 = [5, 12, 8, 130, 44];

const found = array1.find(element => element > 10);

console.log(found);    //  12

Array.prototype.findLast()

findLast()  方法类似 find() ,返回数组中满足提供的测试函数条件的最后一个元素的值。如果没有找到对应元素,则返回 undefined

const array1 = [5, 12, 50, 130, 44];

const found = array1.findLast((element) => element > 45);

console.log(found);  // 130

Array.prototype.findIndex()

findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

findIndex方法对数组中的每个数组索引0..length-1(包括)执行一次callback函数,直到找到一个callback函数返回真实值(强制为true)的值。如果找到这样的元素,findIndex会立即返回该元素的索引。如果回调从不返回真值,或者数组的length为 0,则findIndex返回-1。与某些其他数组方法(如 Array#some)不同,在稀疏数组中,即使对于数组中不存在的条目的索引也会调用回调函数。findIndex不会修改所调用的数组。

const array1 = [5, 12, 8, 130, 44];

const isLargeNumber = (element) => element > 13;

console.log(array1.findIndex(isLargeNumber)); // 3

Array.prototype.findLastIndex()

findLastIndex()  方法类似 findIndex() ,返回数组中满足提供的测试函数条件的最后一个元素的索引。若没有找到对应元素,则返回 -1。

const array1 = [5, 12, 50, 130, 44];

const isLargeNumber = (element) => element > 45;

console.log(array1.findLastIndex(isLargeNumber));  // 3 

Array.prototype.reduce()

reduce()  方法对数组中的每个元素按序执行一个 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)。

const array1 = [1, 2, 3, 4];

// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
  (previousValue, currentValue) => previousValue + currentValue,
  initialValue
);

console.log(sumWithInitial);   //  10

Array.prototype.keys()

keys()  方法返回一个包含数组中每个索引键的 Array Iterator 对象。

const array1 = ['a', 'b', 'c'];
const iterator = array1.keys();

for (const key of iterator) {
  console.log(key);
}

//  0
//  1
//  2

Array.prototype.entries()

entries()  方法返回一个新的 Array Iterator 对象,该对象包含数组中每个索引的键/值对。

const array1 = ['a', 'b', 'c'];

const iterator1 = array1.entries();

console.log(iterator1.next().value);   // : Array [0, "a"]

console.log(iterator1.next().value);   //  Array [1, "b"]

Array.prototype.flat()

flat()  方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回

参数

  • depth 可选

    指定要提取嵌套数组的结构深度,默认值为 1。

const arr1 = [1, 2, [3, 4]];
arr1.flat();  // [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();  // [1, 2, 3, 4, [5, 6]]

const arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);   // [1, 2, 3, 4, 5, 6]

//使用 Infinity,可展开任意深度的嵌套数组
const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// flat() 方法会移除数组中的空项:
const arr5 = [1, 2, , 4, 5];
arr5.flat();  // [1, 2, 4, 5]

Array.prototype.flatMap()

flatMap()  方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为 1 的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。

const arr1 = [1, 2, [3], [4, 5], 6, []];

const flattened = arr1.flatMap(num => num);

console.log(flattened); //  Array [1, 2, 3, 4, 5, 6]