JS数组循环的⽅式以及效率分析对⽐
数组的⽅法
JavaScript发展到现在已经提供了许多数组的⽅法,下⾯这张图涵盖了数组⼤部分的⽅法,这篇⽂章主要说⼀说数组的遍历⽅法,以及各⾃的性能,⽅法这么多,如何挑选性能最佳的⽅法对我们的开发有⾮常⼤的帮助。
数组遍历的⽅法
for
标准的for循环语句,也是最传统的循环语句
var arr = [1,2,3,4,5]
for(var i=0;i<arr.length;i++){
console.log(arr[i])
}
最简单的⼀种遍历⽅式,也是使⽤频率最⾼的,性能较好,但还能优化
优化版for循环语句
var arr = [1,2,3,4,5]
for(var i=0,len=arr.length;i<len;i++){
console.log(arr[i])
}
使⽤临时变量,将长度缓存起来,避免重复获取数组长度,尤其是当数组长度较⼤时优化效果才会更加明显。
这种⽅法基本上是所有循环遍历⽅法中性能最⾼的⼀种
forEach
普通forEach
对数组中的每⼀元素运⾏给定的函数,没有返回值,常⽤来遍历元素
var arr5 = [10,20,30]
var result5 = arr5.forEach((item,index,arr)=>{
console.log(item)
})
console.log(result5)
/*
10
20
30
undefined  该⽅法没有返回值
*/
数组⾃带的foreach循环,使⽤频率较⾼,实际上性能⽐普通for循环弱
原型forEach
由于foreach是Array型⾃带的,对于⼀些⾮这种类型的,⽆法直接使⽤(如NodeList),所以才有了这个变种,使⽤这个变种可以让类似的数组拥有foreach功能。
const nodes = document.querySelectorAll('div')
Array.prototype.forEach.call(nodes,(item,index,arr)=>{
console.log(item)
})
实际性能要⽐普通foreach弱
任意顺序遍历⼀个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。
⼀般常⽤来遍历对象,包括⾮整数类型的名称和继承的那些原型链上⾯的属性也能被遍历。像 Array和 Object使⽤内置构造函数所创建的对象都会继承⾃Object.prototype和String.prototype的不可枚举属性就不能遍历了.
var arr = [1,2,3,4,5]
for(var i in arr){
console.log(i,arr[i])
}  //这⾥的i是对象属性,也就是数组的下标
/**
0 1
1 2
2 3
3 4
4 5 **/
⼤部分⼈都喜欢⽤这个⽅法,但它的性能却不怎么好
在可迭代对象(具有 iterator 接⼝)(Array,Map,Set,String,arguments)上创建⼀个迭代循环,调⽤⾃定义迭代钩⼦,并为每个不同属性的值执⾏语句,不能遍历对象
let arr=["前端","南玖","ssss"];
for (let item of arr){
console.log(item)
}
//前端南玖 ssss
//遍历对象
let person={name:"南玖",age:18,city:"上海"}
for (let item of person){
console.log(item)
}
// 我们发现它是不可以的我们可以搭配Object.keys使⽤
for(let item of Object.keys(person)){
console.log(person[item])
}
// 南玖 18 上海
这种⽅式是es6⾥⾯⽤到的,性能要好于forin,但仍然⽐不上普通for循环
map
map: 只能遍历数组,不能中断,返回值是修改后的数组。
let arr=[1,2,3];
const res = arr.map(item=>{
return item+1
})
console.log(res) //[2,3,4]
console.log(arr) // [1,2,3]
every
对数组中的每⼀运⾏给定的函数,如果该函数对每⼀项都返回true,则该函数返回true
var arr = [10,30,25,64,18,3,9]
var result = arr.every((item,index,arr)=>{
return item>3
})
console.log(result)  //false
js arguments
some
对数组中的每⼀运⾏给定的函数,如果该函数有⼀项返回true,就返回true,所有项返回false才返回false
var arr2 = [10,20,32,45,36,94,75]
var result2 = arr2.some((item,index,arr)=>{
return item<10
})
console.log(result2)  //false
reduce
reduce()⽅法对数组中的每个元素执⾏⼀个由你提供的reducer函数(升序执⾏),将其结果汇总为单个返回值const array = [1,2,3,4]
const reducer = (accumulator, currentValue) => accumulator + currentValue;
// 1 + 2 + 3 + 4
console.duce(reducer));
filter
对数组中的每⼀运⾏给定的函数,会返回满⾜该函数的项组成的数组
// filter  返回满⾜要求的数组项组成的新数组
var arr3 = [3,6,7,12,20,64,35]
var result3 = arr3.filter((item,index,arr)=>{
return item > 3
})
console.log(result3)  //[6,7,12,20,64,35]
性能测试⼯具测试
使⽤⼯具测试性能分析结果如下图所⽰
⼿动测试
我们也可以⾃⼰⽤代码测试:
//测试函数
function clecTime(fn,fnName){
const start = new Date().getTime()
if(fn) fn()
const end = new Date().getTime()
console.log(`${fnName}执⾏耗时:${end-start}ms`) }
function forfn(){
let a = []
for(var i=0;i<arr.length;i++){
// console.log(i)
a.push(arr[i])
}
}
clecTime(forfn, 'for')  //for执⾏耗时:106ms
function forlenfn(){
let a = []
for(var i=0,len=arr.length;i<len;i++){
a.push(arr[i])
}
}
clecTime(forlenfn, 'for len')  //for len执⾏耗时:95ms
function forEachfn(){
let a = []
arr.forEach(item=>{
a.push[item]
})
}
clecTime(forEachfn, 'forEach')  //forEach执⾏耗时:201ms
function forinfn(){
let a = []
for(var i in arr){
a.push(arr[i])
}
}
clecTime(forinfn, 'forin') //forin执⾏耗时:2584ms (离谱)
function foroffn(){
let a = []
for(var i of arr){
a.push(i)
}
}
clecTime(foroffn, 'forof') //forof执⾏耗时:221ms
//  ...其余可⾃⾏测试
结果分析
经过⼯具与⼿动测试发现,结果基本⼀致,数组遍历各个⽅法的速度:传统的for循环最快,for-in最慢
for-len > for > for-of > forEach > map > for-in
javascript原⽣遍历⽅法的建议⽤法:
⽤for循环遍历数组
⽤in遍历对象
⽤f遍历类数组对象(ES6)
⽤Object.keys()获取对象属性名的集合
为何for… in会慢?
因为for … in语法是第⼀个能够迭代对象键的JavaScript语句,循环对象键({})与在数组([])上进⾏循环不同,引擎会执⾏⼀些额外的⼯作来跟踪已经迭代的属性。因此不建议使⽤in来遍历数组
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。