JavaScript-数组自带的一些方法
在JavaScript中,其实数组自带了很多方法,对这些方法我们有必要过一遍,以免用到的时候不知道,然后自己手动实现。当然,手动实现不是不好,只是我们在开发中大部分时间都是快速开发,工期比较紧,不像自己学习的时候开发一样。
还是那句话,在生产中,一般来说,有现成的方法就直接拿来用,不要去自己实现,因为现成的方法已经是经过了很多次的锤炼,你自己去实现,难免出现BUG,当然大佬随意。
以下的方法介绍都取自MDN,也可以直接到MDN进行查看。
方法
Array.prototype.find
返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
console.log(found);
// 输出: 12
参数:
callback:回调函数,有以下三个参数:
- element:当前遍历到的元素。
- index:可选当前遍历到的索引。
- array:可选数组本身。
thisArg:可选执行回调时用作this 的对象。
是否会改变原数组:否。
Array.prototype.push
将一个或多个元素添加到数组的末尾,并返回该数组的新长度,常用方法。
var sports = ["soccer", "baseball"];
var total = sports.push("football", "swimming");
console.log(sports);
// ["soccer", "baseball", "football", "swimming"]
console.log(total);
// 4
同时该方法还可以配合apply()
来进行合并数组操作:
var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];
// 将第二个数组融合进第一个数组
// 相当于 vegetables.push('celery', 'beetroot');
Array.prototype.push.apply(vegetables, moreVegs);
console.log(vegetables);
// ['parsnip', 'potato', 'celery', 'beetroot']
是否会改变原数组:是。
Array.prototype.filter
创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
console.log(result);
// Array ["exuberant", "destruction", "present"]
参数:
callback:回调函数,有以下三个参数:
- element:当前遍历到的元素。
- index:可选当前遍历到的索引。
- array:可选数组本身。
thisArg:可选执行回调时用作this 的对象。
是否会改变原数组:否。
Array.prototype.join
将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。
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.unshift
将一个或多个元素添加到数组的开头,并返回该数组的新长度,虽然用的没有push()
多,但是在某些情况下会用上。
const array1 = [1, 2, 3];
console.log(array1.unshift(4, 5));
// 5
console.log(array1);
// Array [4, 5, 1, 2, 3]
是否会改变原数组:是。
Array.prototype.values
返回一个新的 Array Iterator
对象,该对象包含数组每个索引的值。
const array1 = ['a', 'b', 'c'];
const iterator = array1.values();
for (const value of iterator) {
console.log(value);
}
// 输出: "a"
// 输出: "b"
// 输出: "c"
是否会改变原数组:否。
Array.prototype.some
测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。
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.includes
判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。
非常常用的一个方法,如果要自己去判断数组中是否含有某个值,需要去遍历数组,或者使用二分查找法等等方法。
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.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.fill
用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
const array1 = [1, 2, 3, 4];
// fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// expected output: [1, 2, 0, 0]
// fill with 5 from position 1
console.log(array1.fill(5, 1));
// expected output: [1, 5, 5, 5]
console.log(array1.fill(6));
// expected output: [6, 6, 6, 6]
arr.fill(value[, start[, end]])
:
参数:
- value:用来填充数组元素的值。
- start:可选起始索引,默认值为0。
- end:可选终止索引,默认值为 this.length。
是否会改变原数组:否。
Array.prototype.entries
返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
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.reverse
将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。
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.every
测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
const isBelowThreshold = (currentValue) => currentValue < 40;
const array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every(isBelowThreshold));
// expected output: true
参数:
callback:回调函数,有以下三个参数:
- element:当前遍历到的元素。
- index:可选当前遍历到的索引。
- array:可选数组本身。
thisArg:可选执行回调时用作this 的对象。
是否会改变原数组:否。
Array.prototype.shift
从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
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
返回一个新的数组对象,这一对象是一个由 begin
和 end
决定的原数组的浅拷贝(包括 begin
,不包括end
)。
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"]
是否会改变原数组:否。
Array.prototype.reduce
对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10
// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15
是否会改变原数组:否。
Array.prototype.keys
返回一个包含数组中每个索引键的Array Iterator
对象。
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.flat
会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// expected output: [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat(2));
// expected output: [0, 1, 2, [3, 4]]
数组扁平化,接收一个可选的depth参数。
是否会改变原数组:否。
Array.prototype.map
创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
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.prototype.foreach
的区别是,foreach会改变原数组。
是否会改变原数组:否。
Array.prototype.flatMap
首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。
Array.prototype.flat
和Array.prototype.map
的结合。
是否会改变原数组:否。
Array.prototype.indexOf
返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
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.prototype.forEach
对数组的每个元素执行一次给定的函数。
const array1 = ['a', 'b', 'c'];
array1.forEach(element => console.log(element));
// expected output: "a"
// expected output: "b"
// expected output: "c"
参数:
callback:回调函数,有以下三个参数:
- element:当前遍历到的元素。
- index:可选当前遍历到的索引。
- array:可选数组本身。
thisArg:可选执行回调时用作this 的对象。
是否会改变原数组:是。
Array.prototype.findIndex
返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。
const array1 = [5, 12, 8, 130, 44];
const isLargeNumber = (element) => element > 13;
console.log(array1.findIndex(isLargeNumber));
// expected output: 3
callback:回调函数,有以下三个参数:
- element:当前遍历到的元素。
- index:可选当前遍历到的索引。
- array:可选数组本身。
thisArg:可选执行回调时用作this 的对象。
是否会改变原数组:否。
Array.prototype.reduceRight
接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。
const array1 = [[0, 1], [2, 3], [4, 5]].reduceRight(
(accumulator, currentValue) => accumulator.concat(currentValue)
);
console.log(array1);
// expected output: Array [4, 5, 2, 3, 0, 1]
是否会改变原数组:否。
Array.prototype.toString
返回一个字符串,表示指定的数组及其元素。常用方法。
const array1 = [1, 2, 'a', '1a'];
console.log(array1.toString());
// expected output: "1,2,a,1a"
是否会改变原数组:否。
Array.prototype.copyWithin
浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
const array1 = ['a', 'b', 'c', 'd', 'e'];
// copy to index 0 the element at index 3
console.log(array1.copyWithin(0, 3, 4));
// expected output: Array ["d", "b", "c", "d", "e"]
// copy to index 1 all elements from index 3 to the end
console.log(array1.copyWithin(1, 3));
// expected output: Array ["d", "d", "e", "d", "e"]
是否会改变原数组:否。
Array.prototype.lastIndexOf
返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex
处开始。
const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];
console.log(animals.lastIndexOf('Dodo'));
// expected output: 3
console.log(animals.lastIndexOf('Tiger'));
// expected output: 1
是否会改变原数组:否。
Array.prototype.length
Array
的实例属性。返回或设置一个数组中的元素个数。该值是一个无符号 32-bit 整数,并且总是大于数组最高项的下标,常用方法。
是否会改变原数组:否。
Array.prototype.toLocaleString
返回一个字符串表示数组中的元素。数组中的元素将使用各自的 toLocaleString
方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号 “,”)隔开。
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.splice
通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。常用方法。
在实际开发中一般用来删除某个元素。
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.sort
用原地算法对数组的元素进行排序,并返回数组。
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.concat
用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
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.toSource
返回一个字符串,代表该数组的源代码。一般不用。
是否会改变原数组:否。
Array.isArray
用于确定传递的值是否是一个 Array
。
在JavaScript中,数组其实就是一个对象,如果使用typeof
去检测数组的类型,会发现输出的是一个object
。
let myarr = [12,123,321,321]
console.log(typeof myarr); // object
所以 JavaScript中,要判断是否是数组,就需要用到Array.isArray
方法。
// 下面的函数调用都返回 true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
Array.isArray(new Array('a', 'b', 'c', 'd'))
// 鲜为人知的事实:其实 Array.prototype 也是一个数组。
Array.isArray(Array.prototype);
// 下面的函数调用都返回 false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray(new Uint8Array(32))
Array.isArray({ __proto__: Array.prototype });
至于如何判断一个对象是否是数组,在后面的文章中会讲到。
是否会改变原数组:否。
总结
在JavaScript中,操作数组的时间是非常多的,所以了解一下数组自带的方法还是很有必要,实在记不住,到时候再来查嘛。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!