其实不需要自己去写for循环

前言

在我学习JS的过程中,比如用对一个数组进行一些操作,有时候为了方便(其实并不方便…),就直接用个for循环和一些判断,粗暴地得到结果,但是这并不是个好习惯,因为JavaScript本身就含有了很多已经封装好的数组方法给你用,比起你写的for循环性能不知道好多少,所以本片文章,详细对ES5、ES6中的数组部分我不熟悉的方法做一个总结。

ES5之前

lastIndexOf

之前经常用indexOf来判断一个数组当中有没有每个元素,但是并不知道还有这么一个方法,它和indexOf恰好想法,我们可以理解lastIndexOf是indexOf的贪婪模式,不到最后一个不会停下来:

1
2
var a = [1,2,3,4,5,3]
console.log(a.lastIndexOf(3)) // 5

那么这个有什么用呢?我们可以简单封装个函数,判断数组中的元素(简单类型)是否唯一:

1
2
3
4
5
6
var a = [1,2,3,4,5,3]
function onlyOne(arr, value){
return arr.indexOf(value)===arr.lastIndexOf(value)
}
console.log(onlyOne(a,2)) // true
console.log(onlyOne(a,3)) // false

every

有时候我们需要验证一个数组中是不是每个元素都符合要求,这个时候我们往往会for一个循环,然后来判断,太low啦,还占位置,every就是来判断数组中是不是每个元素都符合预期规定,比如说:

1
2
3
4
var a = [1,2,12,18,5,3]
console.log(a.every(function(value){
return value <= 18 // 若有一个元素返回false,着函数直接返回false,就像&&一样
})) // true

some

如果说every是表示&&的话,那么some就表示||了,如下:

1
2
3
4
var a = [1,2,12,18,5,3]
console.log(a.some(function(value){
return value >= 12 // 若有一个元素返回true,着函数直接返回true,就像&&一样
}))

forEach

当我们获取到一个数组,我们需要利用数组中每个元素做一些运算,那么这个时候,我们就可以用到了forEach,他会遍历每个元素供你使用,就再也不需要写for循环啦:

1
2
3
4
5
6
var a = [1,2,12,18,5,3]
var SumArr = []
a.forEach(function(value){
SumArr.push(value+6)
})
console.log(SumArr) // [ 7, 8, 18, 24, 11, 9 ]

map

map同样也是遍历数组总的每个元素,但是最不同的是,map的有着直接的返回值,这个返回值就是在内部函数中经过处理的元素,它返回的是一整个数组,如:

1
2
3
4
5
6
7
8
9
10
var a = [1,2,12,18,5,3]
var SumArr = []
SumArr = a.map(function(value){
if(value >= 12){
return // 无返回值即是undefined
}else{
return value
}
})
console.log(SumArr) // [ 1, 2, undefined, undefined, 5, 3 ]

filter

我们注意到,在上面的map中,原数组元素的个数是多少,map就返回多少,那么假如我要筛除掉一些我不想要的元素的,比如上面SumArr中的undefined元素:

1
2
3
4
5
6
7
8
9
var SumArr = [ 1, 2, undefined, undefined, 5, 3 ]
SumArr = SumArr.filter(function(value){
if (value===undefined) {
return false // false则筛除
} else {
return true
}
})
console.log(SumArr) // [ 1, 2, 5, 3 ]

reduce

这个就有点麻烦,其实也很简单,reduce就是一个累加器,它接受两个参数,第一个参数是当前累加量,第二个参数是下一轮遍历的数组,我们来看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var SumColor = [ 'red','pink','green','yellow' ]
var allColor = SumColor.reduce(function(currentValue, nextValue){
console.log('------开始累加--------')
console.log('当前累加值:',currentValue)
console.log('数组下一个值:',nextValue)
return currentValue+nextValue
})
console.log("最终累加值:",allColor)
// ------开始累加--------
// 当前累加值: red
// 数组下一个值: pink
// ------开始累加--------
// 当前累加值: redpink
// 数组下一个值: green
// ------开始累加--------
// 当前累加值: redpinkgreen
// 数组下一个值: yellow
// 最终累加值: redpinkgreenyellow

它最终返回的是累加器最后一次累加,所计算的值,还有一个功能和他类似,但是累加顺序相反的方法,叫reduceRight,大家自己试一试,不在赘述。

ES6新增方法

Array.from

有个概念叫做类数组对象,这种对象很多时候会用call或者apply来“借用”数组的方法,ES6为了方便操作这种对象,直接添加了一个方法,将类数组对象转化为数组:

1
2
3
4
5
6
7
8
var likeArr = {
0: 'a',
1: 'b',
2: 'c',
3: 'd',
length: 4 // 类数组对象必须要含有正确的length
}
console.log(Array.from(likeArr)) // [ 'a', 'b', 'c', 'd' ]

copyWithin

假如需要调整数组内部的元素,用其中的某个元素将其另外元素覆盖,返回修改后的值,并且这次修改直接影响到数组本身。

1
2
3
let Arr = [1,2,3,4,5,6]
console.log(Arr.copyWithin(0,2)) // [ 3, 4, 5, 6, 5, 6 ]
console.log(Arr) // [ 3, 4, 5, 6, 5, 6 ]

find

这个顾名思义就是在数组中查找元素,那么和indexOf有什么区别呢?我们之前看到,用indexOf时,只能查找与查找条件相等的值,那么如果说,我设定一个条件,需要值满足某个条件,如果有,则返回这个值:

1
2
3
4
5
6
let Arr = [1,2,3,4,5,6]
console.log(Arr.find(function (value) {
if (value/2 === 3){
return value
}
})) // 6

总结

这里并没有列出所有数组的方法,只是提到了比较容易混淆或者不熟悉的几个方法,这里做一个总结,提醒自己若要对数组操作时,切记先想想是否含有原生方法,再去考虑自己遍历,写出更优秀简洁的代码。