数组方法不完全指北
数组中有很多方法,在日常开发中合理选择方法可以简化我们的代码。当然合理选择的前提就是你对数组上方法了然于胸,说到数组脑海中自然而然的就浮现出push、shift、filter、foreach、map等等方法,并且对他们的参数、返回值以及使用场景十分清晰。这篇文章就重点总结数组上的方法,做一个全面的总结。我在这里将他们分成两个大区域:ES6之前和ES6之后
ES6之前
toString
1 | let arr = [1,2,3,4,5] |
toString方法可以将我们的数组转换成字符串toString方法可以将我们的多维数组扁平化后转换成字符串
join
1 | let arr = [1,2,3,4,5] |
join方法可以将我们的数组按照指定字符进行拼接 默认值是逗号 也就是默认情况下和toString效果一样- 当然当涉及到多维数组的情况下,他们的表现有不一致,他只能处理第一层,如果使用默认值,他的表现和
toString一致,但是这不是join的功劳,嵌套在里面的数组默认就是用逗号分隔的,而不是`join`方法的默认值起的作用
思考下
join和String.prototype.split方法的区别:他们属于逆运算
1 | let arr = [1,2,[3,4,[5,6]],7] |
数组的堆栈方法 push | pop | unshift | shift
1 | let arr = [1, 2, 3] |
- 这四个方法常见、常用,两个头尾新增,两个头尾移除。新增返回长度,移除返回移除的项
数组的排序 reverse | sort
这两个方法都是用来对数组进行排序的,其中reverse方法是将数组倒序处理,而sort方法根据回调函数能做到不同的效果,他们操作的都是原数组
1 | let arr = [1, 2, 3, 4, 5] |
数组拼接 concat
1 | let arr = [1, 2] |
- 经过上面几个demo,可以发现
concat返回的是一个新的数组,原数组不受影响 concat方法可以简单处理单层数组,多维数组的合并就并不会进行扁平化
数组的删改 slice | splice (左开右闭)
slice:左开右闭区间:第一个参数
start是开始的下标(包含),第二个参数end是结束的下标(不包含),如果没有结束参数 默认从start一直截取到最后1
2
3
4
5
6
7
8
9
10
11
let arr = [1, 2, 3, 4]
const newArr = arr.slice() // 可以用于生成一个新的数组
console.log(arr == newArr); // false
console.log(arr, 'arr'); // [ 1, 2, 3, 4 ] arr 原数组没有有受到影响
console.log(arr.slice(2), 'slice'); // [ 3, 4 ] slice
console.log(arr.slice(2, 3)); // [3] 从下标2开始(包含) 到下标为3的项(不包含)
//如果给负数的情况下 就是意味着从后往前开始计算 最后一个为-1,一次往前推,同样满足左开右闭
console.log(arr.slice(-3, -1)); //[2,3]splice:同样满足左开右闭区间,和
slice最大的区别就是这个会影响原数组,其次根据参数的不同,他可以做到删除、插入、修改等操作1
2
3let arr1 = [1, 2, 3, 4, 5]
console.log(arr1.splice(2), 'splice'); // [ 3, 4, 5 ] splice
console.log(arr1, 'arr1'); // [ 1, 2 ] arr1 原数组收到了影响参数:第一个参数是开始的位置,第二个参数是截取的长度,第三个参数是插入什么元素
1
2
3
4
5
6
7let arr1 = [1, 2, 3, 4, 5]
console.log(arr1.splice(2, 3, 7, 8, 9)); // [ 3, 4, 5 ] 返回的是删除了哪些元素
console.log(arr1); // [ 1, 2, 7, 8, 9 ] 可以发现原数组发生变化了,从index为2开始删除3个元素,插入6、7、8
console.log(arr1.splice(2, 0, 10, 11, 12)); // [] 删除0个 所以返回空数组
console.log(arr1); //[1, 2, 10, 11, 12, 3, 4, 5] 可以看出是插入在下标为2的前面 说白了就是把需要插入的元素从下标为2开始进行插入操作
数组的查找 indexOf | lastIndexOf
- 返回的是下标
1 | let arr = [1, 2, 3, 4, 5] |
ES6之后
fill 填充数组
第一个参数是要填充的元素,第二个参数是开始的下标,第三个参数是结束的下标,默认全部填充,同样满足左闭右开区间特性
1 | let arr = new Array(5) |
find | findIndex
数组实例的find()方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined
数组实例的findIndex()方法的用法与find()方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1
1 | let arr = [1, 2, 3, 4, 5, 6, 7] |
Array的静态方法
Array.of
使用该方法可以生成一个由参数组成的数组
1 | console.log(Array.of(2, 3, 4)); // [2, 3, 4] |
Array.from
使用该方法同样可以生成一个有参数组成的数组,但是他在传递类数组表现和Array.of却并不一致,form方法可以将类数组转换成真正的数组
1 | function foo() { |
数组的迭代方法 ( 遍历 )
数组的遍历应该是前端接触数组用的最多的场景,基本上遇到数组很难避免遍历,所以这里我抽出来,单独放一个模块。
keys | values | entries
ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历
1 | let arr = [1, 2, 3, 4, 5] |
forEach
forEach没有返回值,即便指定返回值,也是返回的undefinedforEach有两个参数,第一个参数是回调函数即为每个元素执行怎样的操作,第二个可选参数是this指向,函数内部的this指向什么。回调函数有三个参数,第一个代表当前项,第二个是下标,第三个则是原数组,就是遍历的那个数组forEach无法被打断1
2
3
4
5
6
7
8
9let arr = [1, 2, 3, 4, 5]
arr.forEach(item => {
console.log(item);
// 1 0 [ 1, 2, 3, 4, 5 ]
// 2 1 [ 1, 2, 3, 4, 5 ]
// 3 2 [ 1, 2, 3, 4, 5 ]
// 4 3 [ 1, 2, 3, 4, 5 ]
// 5 4 [ 1, 2, 3, 4, 5 ]
});
tips:下面几个方法如果谈到第二个参数用来绑定this指向的话,一定要注意不要写成箭头函数,箭头函数是无法绑定this的,这一点需要敏感
map
map和forEach的使用高度相似,forEach是没有返回值的,但是map是拥有返回值的,可以简单理解为:我们给定一个函数,使用map方法后会将数组的每一项走执行一次这个函数,并且返回一个数组,新数组和旧数组呈印射关系map有两个参数,第一个参数是回调函数即为每个元素执行怎样的操作,第二个可选参数是this指向,函数内部的this指向什么。回调函数有三个参数,第一个代表当前项,第二个是下标,第三个则是原数组,就是遍历的那个数组,这三个参数和forEach保持一致
1 | let arr = [1, 2, 3, 4, 5] |
filter
filter过滤函数,如果我们需要对数组的元素进行过滤处理,那么肯定优先考虑filter函数,它的返回值应该是一个布尔值,通过这个布尔值来决定要不要过滤当前项
- 参数和
map、forEach方法一致,不多赘述了 - 区别就在于返回值,简单理解为:将数组中满足条件的项返回出去,并且组成一个新的数组
1 | let arr = [1, 2, 3, 4, 5] |
some | every
some 用于判断数组有没有存在符合预期的项,有一项就行,evert 需要数组中所有项都满足条件。他们的返回值都是布尔值
1 | const arr = [1, 2, 3, 4, 5] |
万金油方法 reduce
我们使用灵活使用reduce方法可以做出各种各样的骚操作。比如说MDN对map方法的示例。当然最经典的就是求和
- 参数: 第一个参数是回调函数,第二个是默认值,会作为第一次循环的时候回调函数的第一个参数
- 注意:如果不给默认值,就会少执行一次循环。数组的第一项直接作为回调函数的第一个参数,第二个参数从第二项开始
求和
1 | let arr = [1, 2, 3, 4, 5] |
这里第一次循环的时候,由于没有给出默认值,所以pre的值是数组的第一项,也就是1,cur是数组的第二项,说白了跳过循环第一项了。如果要避免这种情况,可以给个默认值0,这样cur就是从数组的第一项开始了
对象中的某个字段进行求和
1 | let arr = [ |
这里就一定要给默认值,不然的话第一次循环pre拿到的是一个对象,求和之后就会出问题









