一、简介
JavaScript 有六大基础类型,它们分别是:字符串 (String) 、数字 (Number) 、布尔 (Boolean) 、空 (Null) 、未定义 (undefined) 和符号 (Symbol) ;其中引用数据类型 (对象类型) 有对象 (Object) 、数组 (Array) 和函数 (Function) 。还有两个特殊的对象分别是正则 (RegExp) 和 日期 (Date) 。
今天要具体讲解的便是其中的一个引用数据类型:数组 (Array) ,数组可以用于在单个变量中存储多个值,并且数组内的元素类型可以不尽相同。比如:
var arr = [1, 'hello', true, undefined, {...}];
其中,数组有非常多的实例方法,包括一些基础的pop, push方法等,它们均属于数组的实例方法。接下来就具体来讲解一下其中一些比较常用的方法。
二、实例方法
1. pop()
pop() 方法的作用是:删除数组中的最后一个元素,并且返回被删除元素的值。
用生活中的例子来说,也许就像有些学校会举办分班考试,其中吊车尾或者叫最后一名(最后一个元素) ,会从火箭班 (数组) 中被踢出去 (删除),并且会告知 (返回) 该学生 (元素) 被踢出去了。
具体代码示例如下:
var array = [2, 4, 6, 8, 10];
console.log(array.pop());
// 控制台输出: 10
console.log(array);
// 控制台输出: Array [2, 4, 6, 8]
由上方代码不难看出,pop() 方法还会更改数组的长度 (打比方就是倒数第一被踢出了班级, 人数数量当然会减1) 。
2. push()
push() 方法的作用是:将指定的元素添加到数组的末尾,并返回新的数组长度。
push() 方法就好像和pop() 是相反的,它会将平行班中的优秀学生们(指定的元素),全部加入到火箭班 (数组) 中,由于是新添加的学生 (元素),就会暂时将他们排在班级末尾(数组的末尾)。
具体代码示例如下:
var array = [1, 3, 5, 7];
console.log(array.push(9));
// 控制台输出: 5
console,log(array);
// 控制台输出: Array [1, 3, 5, 7, 9]
console.log(array.push(11, 13));
// 控制台输出: 7
console.log(array);
// 控制台输出: Array [1, 3, 5, 7, 9, 11, 13]
由上方代码不难看出,添加的元素数量是可以多个的。
3. shift()
shift() 方法的作用是:删除数组中的第一个元素,并返回该元素的值。同样的,此方法也会更改数组的长度。
shift() 方法和 pop() 方法同样都是删除,但是shift() 方法会将第一的优等生保送出去 (删除第一个元素),而pop() 方法是删除数组的最后一个元素。
具体代码示例如下:
var array = [5, 10, 15];
console.log(array.shift());
// 控制台输出: 5
console.log(array);
// 控制台输出: Array [10, 15]
4. unshift()
unshift() 方法的作用是:将指定的元素添加到数组的开头,并返回数组的新长度。
unshift() 方法和 push() 方法同样都是添加,但是unshift() 方法会将火箭班最棒的学生 (从数组开头) 插入 (添加) 到平行班 (数组) 里,并告知 (返回) 添加了学生后的班级总人数 (新数组长度)。而shift() 方法是从数组的最后一个开始添加。
具体代码示例如下:
var array = [12, 15, 18, 21];
console.log(array.unshift(3));
// 控制台输出: 5
console.log(array);
// 控制台输出: Array [3, 12, 15, 18, 21]
console.log(array.unshift(6, 9));
// 控制台输出: 7
console.log(array);
// 控制台输出: Array [3, 6, 9, 12, 15, 18, 21]
由上方代码不难看出,unshift() 方法添加元素的数量也可以是多个的。
5. slice()
slice() 方法的作用是:指定一个范围或起始索引,将原数组拷贝 (浅拷贝) 为一个新的数组对象,并将其返回;且原数组不会被改变。
slice() 方法可以传递0个、1个或2个参数,分别代表拷贝所有元素、start 或start 和end。其中它们的值代表着对应的数组元素的索引。
slice() 方法就很像老师从班级中间挑出几位成绩连续的学生(有start和 end两个参数),当然也可以除了前几名的剩余学生(有start 参数),甚至可以从后往前挑选学生 (索引为负数),也可以直接选取全班 (不传参);并且最后将挑选出的学生统计出来(返回新的数组对象)。
具体代码示例如下:
var array = [4, 8, 12, 16, 20];
console.log(array.slice(2));
// 控制台输出: Array [12, 16, 20]
console.log(array.slice(1, 3));
// 控制台输出: Array [8, 12, 16]
console.log(array.slice(-2));
// 控制台输出: Array [16, 20]
console.log(array.slice());
// 控制台输出: Array [4, 8, 12, 16, 20]
不难看出其中的start 和end 参数均为数组元素的索引,且符合左闭右闭 (即左右均包含) 的原则;当参数为负数时,是从数组的最后一位开始进行拷贝。
6. reverse() & toReversed()
reverse() 方法的作用是:将数组中的元素进行反转 (即原数组的第一个元素会变为最后一个,最后一个元素变为第一个),并返回同一数组的引用;即会将数组中的元素顺序翻转,变为与之前相反的方向。该方法会改变原数组。
如果你要在不改变原始数组的情况下反转数组内的元素,你可以使用 toReversed() 方法。
具体代码示例如下:
var array1 = [15, 30, 45, 60];
// reverse()
array1.reverse();
console.log(array1);
// 控制台输出: Array [60, 45, 30, 15]
var array2 = [2, 4, 6];
// toReversed()
var array3 = array2.toReversed();
console.log(array2);
// 控制台输出: Array [2, 4, 6]
console.log(array3);
// 控制台输出: Array [6, 4, 2]
7. sort() & toSorted()
sort() 方法的作用是:将数组中的元素直接进行排序,并返回对相同数组的引用。默认的排序方法是将元素转换为字符串,然后按照它们的UTF-16 码元值升序排序;同样的,该方法会改变原数组。
sort() 方法可以传递定义排序顺序的函数。为a 和 b,分别是两个用于比较的元素,不能为undefined;如果a 小于b,返回值为负数,如果a 大于b ,返回值为正数,如果两个元素相等,返回值为 0,NaN 被视为0。如果不传递此排序函数,就会用默认的排序方法排序。
简单来说,返回 a - b 就是从小往大排序,返回 b - a 就是从大往小排序。示例如下:
var array = [6, 3, 12, 15, 9];
// 比较函数的一种写法 (单独封装)
function compare1(a, b) {
return a - b;
}
array.sort(compare1); // [3, 6, 9, 12, 15]
// 比较函数的匿名式写法
array.sort(function(a, b) { // [15, 12, 9, 6, 3]
return b - a;
});
如果你要在不改变原始数组的情况下反转数组内的元素,你可以使用 toSorted() 方法。
8. concat()
concat() 方法的作用是:用于将两个或多个数组合并为一个数组。此方法不会改变现有数组,而是会返回一个新数组。
由于是多个数组合并,所以参数可以传多个值。
具体代码示例如下:
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
var array3 = [7, 8, 9];
var concatArr1 = array1.concat(array2);
console.log(concatArr1);
// 控制台输出: Array [1, 2, 3, 4, 5, 6]
var concatArr2 = array1.concat(array2, array3);
console.log(concatArr2);
// 控制台输出: Array [1, 2, 3, 4, 5, 6, 7, 8, 9]
9. indexOf()
indexOf() 方法对于String (字符串) 来说也有,且用法和返回值几乎是相同的。在数组中,indexOf() 方法的作用是会返回数组中第一次出现给定的元素的下标,如果不存在就会返回 -1。
indexOf() 可以传两个参数,一个是指定的元素内容,另一个是开始检索的下标 (fromIndex),即表示从下标为几的元素开始查找。
具体代码示例如下:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(arr.indexOf(5));
// 控制台输出: 4
console.log(arr.indexOf(8, 5)); // 从下标为5 的元素开始查找
// 控制台输出: 7
console.log(arr.indexOf(1, 5));
// 控制台输出: -1
console.log(arr.indexOf(999));
// 控制台输出: -1
10. join()
join() 方法对于String (字符串) 来说也有这个方法,并且用法是差不多的。在数组或者类数组对象中,join() 方法的作用是:将所有元素连接成一个字符串并返回这个字符串,用逗号或指定的分隔符来分隔。如果数组只有一个元素,那么将返回该元素而不使用分隔符。
所以不难发现join() 方法是可以携带一个参数的,这个参数就是分隔符字符串 (separator),如果省略则默认用英文逗号 (,) 分隔;如果分隔符字符串是空字符串 (""),则所有元素之间都会没有任何字符。
具体代码示例如下:
var element = ['hello'];
var elements = ['red', 'green', 'blue', 'alpha'];
console.log(element.join());
// 控制台输出: "hello"
console.log(elements.join());
// 控制台输出: "red,green,blue,alpha"
console.log(elements.join(''));
// 控制台输出: "redgreenbluealpha"
console.log(elements.join('-'));
// 控制台输出: "red-green-blue-alpha"
其中需要注意的点是,如果在数组中,有一个元素是undefined 或null ,它将会被转换为空字符串,而不会是"undefined" 或"null" 。
11. find() & findIndex()
find() 方法的作用是:会返回数组中满足提供的测试函数的第一个元素的值,如果没有则会返回undefined。
同时,如果你需要在数组中找到对应元素的索引,你应该使用findIndex() 方法。对于findIndex() 方法来说,会返回数组中满足提供的测试函数的第一个元素的索引。如果没有在数组中找到对应的元素,则会返回-1。
具体代码示例如下:
var array = [3, 8, 24, 7, 9, 63];
// find()
var found = array.find((element) => element > 20);
console.log(found);
// 控制台输出: 20
// findIndex
var foundIndex = array.findIndex((element) => element > 20);
console.log(foundIndex);
// 控制台输出: 2
12. findLast() & findLastIndex()
findLast() 方法和find() 的功能一样,只是findLast() 方法的作用是:反向迭代数组,并返回满足提供的测试函数的第一个元素的值。如果没有找到对应的元素,则返回undefined。
同时,如果你需要在数组中找到最后一个匹配元素的索引,你应该使用findLastIndex() 方法。对于findLastIndex() 方法来说,会返回反向迭代的数组中,满足提供的测试函数的第一个元素的索引。如果没有找到对应的元素,则返回-1。
其中对反向迭代做出解释。换句话说,就是从后往前检索 (原本的find() 方法等是从前往后) 。
具体代码示例如下:
var array = [2, 9, 18, 3, 7, 21];
// findLast()
var foundLast = array.findLast((element) => element > 15);
console.log(foundLast);
// 控制台输出: 21
// findLastIndex()
var foundLastIndex = array.findLastIndex((element) => element < 15);
console.log(foundLastIndex);
// 控制台输出: 4
13. includes()
includes() 方法的作用是:用来判断一个数组内是否包含一个指定的值;如果包含则返回true,不包含则返回false ;即返回一个布尔值 (boolean) 。
includes() 方法可传两个参数,其中查找的值 (searchElement) 为必需的参数,开始搜索的索引 (fromIndex) 为可选参数,即从数组对应的索引开始搜索;默认从0开始,如果fromIndex 大于数组的长度,则不会搜索数组并直接返回false 。
具体代码示例如下:
var array = [3, 6, 9];
console.log(array.includes(6));
// 控制台输出: true
console.log(array.includes(369));
// 控制台输出: false
console.log(array.includes(9, 1));
// 控制台输出: true
console.log(array.includes(3, 1));
// 控制台输出: false
14.toString()
toString() 方法的作用是:返回一个字符串,表示指定的数组及其元素。
具体代码示例如下:
var array = [5, 6, "1e"];
console.log(array.toString());
// 控制台输出: "5,6,1e"
15. some() & every()
some() 方法和every() 方法的作用很相似,它们的返回值均为布尔值 (boolean) 且不会修改原数组。它们的区别便是判断的条件。
some() 方法测试数组中是否至少有一个元素通过了由提供的函数实现的测试,即有一个符合则返回true ,全都不符合则返回false ;而every() 方法是测试一个数组内的所有元素是都都能通过指定函数的测试,即有一个不合符则返回false ,全都符合才返回true。
具体代码示例如下:
var array = [10, 20, 30, 40, 50];
// 提供的函数 (即判断条件)
var condition1 = (element) => element % 5 === 0;
var condition2 = (element) => element > 30;
var condition3 = (element) => element > 60;
// some() 方法
console.log(array.some(condition2));
// 控制台输出: true
console.log(array.some(condition3));
// 控制台输出: false
// every() 方法
console.log(array.every(condition1));
// 控制台输出: true
console.log(array.every(condition2));
// 控制台输出: false
16. fill()
fill() 方法的作用是:用一个固定值去填充一个数组,从起始索引 (默认为0) 到终止索引 (默认为数组的长度) 内的全部元素。它的返回值为修改后的数组。
具体代码示例如下:
var array = [11, 22, 33, 44];
console.log(array.fill(111, 1, 2));
// 控制台输出: Array [11, 111, 111, 44]
console.log(array.fill(111, 1));
// 控制台输出: Array [11, 111, 111, 111]
console.log(array.fill(111));
// 控制台输出: Array [111, 111, 111, 111]
17. splice() & toSpliced()
splice() 方法会直接对原数组进行修改,它的作用是:直接移除或者替换已存在的元素或添加新的元素。该方法的返回值为一个包含了删除的元素的数组,如果没有删除任何元素,则返回空数组。
如果你想创建一个删除或替换部分内容而不会改变原数组的新数组,你应该使用toSpliced() 方法。它的返回值为一个新数组,包括start 之前的元素和删除后的元素和所有新增的元素。
splice() 可以传多个参数,其中开始的索引 (start) 是必需的:
splice(start)
splice(start, deleteCount)
splice(start, deleteCount, item1)
splice(start, deleteCount, item1, item2, /* ..., */, itemN)
splice() 方法的参数中,deleteCount 表达从start 开始删除的元素数量。如果该值为0或负数,则不会移除任何元素。
item1-itemN 表达从start 开始要加入要数组中的元素。如果不指定任何元素,则splice() 将只从数组中删除元素。
具体代码示例如下:
var array = [1, 3, 4, 5];
// 在索引为1的位置添加
array.splice(1, 0, 2);
console.log(array);
// 控制台输出: Array [1, 2, 3, 4, 5]
// 在索引为3的地方删除2个元素并添加元素
array.splice(3, 2, 8, 9, 10);
console.log(array);
// 控制台输出: Array [1, 2, 3, 8, 9, 10]
18. forEach()
forEach() 方法属于最基础的遍历,所以它的作用是:对数组内的每个元素执行一次给定的函数;且该方法没有返回值。
具体代码示例如下:
var array = ['x', 'y', 'z'];
// forEach() 遍历打印数组内的元素
array.forEach((element) => console.log(element));
// 控制台输出:
// "x"
// "y"
// "z"
forEach() 方法可以传两个参数,一个是回调函数 (callbackFn) ,另一个是可选的参数 (thisArg),用作执行回调函数时的this 的值;在这里着重讲解回调函数内的三个参数:
/* ... */.forEach((element, index, array) => {
// ...
})
- element 是数组当前正在处理的元素,即数组中的每个元素都会被遍历,作为element;
- index 是数组当前正在处理的元素的索引;
- array 是调用了forEach() 方法的数组的本身。
当然,由于它们是形参,名称是可以自己决定的,而并非一定为上面的三个单词。
注意:后面提及到的参数内携带有回调函数的,基本格式与参数均与此格式相同 (如:map() 、fliter() 等) 。
19. map()
map() 方法可以看作forEach() 方法的进阶版,因为map() 方法会返回原数组中的每个元素调用一次提供的函数后的新数组。所以map() 方法的作用是:创建一个新数组。
具体代码示例如下:
var array = [2, 4, 6, 8];
var mapper = array.map((element) => element * 10);
console.log(mapper);
// 控制台输出: Array [20, 40, 60, 80]
20. flat() & flatMap()
flat() 方法的作用是:创建(返回) 一个新的数组,并根据指定深度递归地将所有子数组元素拼接到新的数组中。深度默认为1。
flatMap() 方法会对数组中的每个元素应用给定的回调函数,然后将结果展开一级,返回一个新数组;它其实等价于在调用map() 方法后再调用深度为1的flat() 方法 ( 即 arr.map(...args).flat() ) ,并且比分别调用这两个方法高效一些。
具体代码示例如下:
var array1 = [0, 1, [2, [3, [4, 5]]];
// flat() 方法
console.log(array1.flat());
// 控制台输出: Array [0, 1, 2, Array [3, Array [4, 5]]]
console.log(array1.flat(2));
// 控制台输出: Array [0, 1, 2, 3, Array [4, 5]]
console.log(array1.flat(Infinity));
// 控制台输出: Array [0, 1, 2, 3, 4, 5]
// flatMap() 方法
var array2 = [1, 2, 1];
var fm = arr2.flatMap((element) => element === 2 ? [2, 2] : 1);
console.log(fm);
// 由于会调用深度为1的flat() 方法, 故输出如下:
// 控制台输出: Array [1, 2, 2, 1]
21. filter()
filter() 方法创建(返回) 给定数组一部分的浅拷贝,其中包含通过所提供函数实现的测试的所有元素。换句话说,就是筛选出符合条件的元素。
具体代码示例如下:
var array = [3, 8, 2, 5, 7, 4, 1, 6, 9, 0];
var result = array.filter((num) => num >= 5);
console.log(result);
// 控制台输出: Array [8, 5, 7, 6, 9]
22. reduce() & reduceRight()
reduce() 方法可以将其称之为:累加器 (accumulator),它的作用是:对数组中的每一个元素按序执行一个提供的reducer 函数,每一次运行reducer 会将先前元素的计算结果作为参数传入,最后将结果汇总为单个的返回值。
如果需要回调函数从数组索引为0 的元素开始执行,则需要传递初始值。否则,索引为0 的元素将被用作初始值,迭代器将从第二个元素开始执行(即从索引为1 而不是0 的位置开始)。
虽然reduce() 方法的参数也是传递一个回调函数 (callbackFn),但是其内有四个参数:
- accumulator:上一次调用回调函数的结果。在第一次调用时,如果指定了初始值(initialValue),则为指定的值;默认为array[0] 的值;
- currentValue:当前元素的值。在第一次调用时,如果指定了初始值 (initialValue),则为array[0] ;默认为array[1] ;
- currentIndex:当前元素的值 (currentValue) 在数组中的索引位置。在第一次调用时,如果指定了初始值 (initialValue),则为0 ,否则为1 。
- array:调用了reduce() 的数组本身。
另外一个可选的参数就是上面提及到的初始值 (initialValue)。
注意:如果数组为空且为提供initialValue,则会抛出异常(报错)。
对于从右至左遍历的相似累加的方法,你可以使用 reduceRight() 方法。
具体代码示例如下:
var array = [1, 2, 3, 4];
var initialValue = 0;
var sum = array.reduce(((accumulator, currentValue) =>
accumulator + currentValue), initialValue);
console.log(sum);
// 控制台输出: 10
三、总结
以上便是数组中一些常见和常用的实例方法了,当然数组的方法远远不只有这些,包括还有at() 方法、copyWithin() 方法、entries() 方法、toLocalString() 方法等等。但是学习的过程是慢慢理解、逐渐消化吸收的,同时也要先掌握重点和重要的内容,学有余力再去了解学习其他的内容。
希望这篇关于JavaScript 的Array的实例方法的介绍可以帮助到你的学习。如果有异议或其他的看法欢迎来发表自己的看法以及对此文章进行批评指正!