参考答案:
标准的for循环语句,也是最传统的循环语句
1var arr = [1,2,3,4,5] 2for(var i=0;i<arr.length;i++){ 3 console.log(arr[i]) 4}
最简单的一种遍历方式,也是使用频率最高的,性能较好,但还能优化
优化版for循环语句
1var arr = [1,2,3,4,5] 2for(var i=0,len=arr.length;i<len;i++){ 3 console.log(arr[i]) 4}
使用临时变量,将长度缓存起来,避免重复获取数组长度,尤其是当数组长度较大时优化效果才会更加明显。
这种方法基本上是所有循环遍历方法中性能最高的一种
普通forEach
对数组中的每一元素运行给定的函数,没有返回值,常用来遍历元素
1var arr5 = [10,20,30] 2var result5 = arr5.forEach((item,index,arr)=>{ 3 console.log(item) 4}) 5console.log(result5) 6/* 710 820 930 10undefined 该方法没有返回值 11*/
数组自带的foreach循环,使用频率较高,实际上性能比普通for循环弱
原型forEach
由于foreach是Array型自带的,对于一些非这种类型的,无法直接使用(如NodeList),所以才有了这个变种,使用这个变种可以让类似的数组拥有foreach功能。
1const nodes = document.querySelectorAll('div') 2Array.prototype.forEach.call(nodes,(item,index,arr)=>{ 3 console.log(item) 4})
实际性能要比普通foreach弱
任意顺序遍历一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。
一般常用来遍历对象,包括非整数类型的名称和继承的那些原型链上面的属性也能被遍历。像 Array和 Object使用内置构造函数所创建的对象都会继承自Object.prototype和String.prototype的不可枚举属性就不能遍历了.
1var arr = [1,2,3,4,5] 2for(var i in arr){ 3 console.log(i,arr[i]) 4} //这里的i是对象属性,也就是数组的下标 5/** 60 1 71 2 82 3 93 4 104 5 **/
大部分人都喜欢用这个方法,但它的性能却不怎么好
在可迭代对象(具有 iterator 接口)(Array,Map,Set,String,arguments)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句,不能遍历对象
1let arr=["前端","面试题宝典","真好用"]; 2 for (let item of arr){ 3 console.log(item) 4 } 5 6//遍历对象 7let person={name:"前端面试题宝典",age:18,city:"上海"} 8for (let item of person){ 9 console.log(item) 10} 11// 我们发现它是不可以的 我们可以搭配Object.keys使用 12for(let item of Object.keys(person)){ 13 console.log(person[item]) 14} 15// 南玖 18 上海
这种方式是es6里面用到的,性能要好于forin,但仍然比不上普通for循环
map: 只能遍历数组,不能中断,返回值是修改后的数组。
1let arr=[1,2,3]; 2const res = arr.map(item=>{ 3 return item+1 4}) 5console.log(res) //[2,3,4] 6console.log(arr) // [1,2,3]
对数组中的每一运行给定的函数,如果该函数对每一项都返回true,则该函数返回true
1var arr = [10,30,25,64,18,3,9] 2var result = arr.every((item,index,arr)=>{ 3 return item>3 4}) 5console.log(result) //false
对数组中的每一运行给定的函数,如果该函数有一项返回true,就返回true,所有项返回false才返回false
1var arr2 = [10,20,32,45,36,94,75] 2var result2 = arr2.some((item,index,arr)=>{ 3 return item<10 4}) 5console.log(result2) //false
reduce()
方法对数组中的每个元素执行一个由你提供的reducer函数(升序执行),将其结果汇总为单个返回值
1const array = [1,2,3,4] 2const reducer = (accumulator, currentValue) => accumulator + currentValue; 3 4// 1 + 2 + 3 + 4 5console.log(array1.reduce(reducer));
对数组中的每一运行给定的函数,会返回满足该函数的项组成的数组
1// filter 返回满足要求的数组项组成的新数组 2var arr3 = [3,6,7,12,20,64,35] 3var result3 = arr3.filter((item,index,arr)=>{ 4 return item > 3 5}) 6console.log(result3) //[6,7,12,20,64,35]
使用工具测试性能分析结果如下图所示
我们也可以自己用代码测试:
1//测试函数 2function clecTime(fn,fnName){ 3 const start = new Date().getTime() 4 if(fn) fn() 5 const end = new Date().getTime() 6 console.log(`${fnName}执行耗时:${end-start}ms`) 7} 8 9function forfn(){ 10 let a = [] 11 for(var i=0;i<arr.length;i++){ 12 // console.log(i) 13 a.push(arr[i]) 14 } 15} 16clecTime(forfn, 'for') //for执行耗时:106ms 17 18function forlenfn(){ 19 let a = [] 20 for(var i=0,len=arr.length;i<len;i++){ 21 a.push(arr[i]) 22 } 23} 24clecTime(forlenfn, 'for len') //for len执行耗时:95ms 25 26function forEachfn(){ 27 let a = [] 28 arr.forEach(item=>{ 29 a.push[item] 30 }) 31} 32clecTime(forEachfn, 'forEach') //forEach执行耗时:201ms 33 34function forinfn(){ 35 let a = [] 36 for(var i in arr){ 37 a.push(arr[i]) 38 } 39} 40clecTime(forinfn, 'forin') //forin执行耗时:2584ms (离谱) 41 42function foroffn(){ 43 let a = [] 44 for(var i of arr){ 45 a.push(i) 46 } 47} 48clecTime(foroffn, 'forof') //forof执行耗时:221ms 49 50// ...其余可自行测试
经过工具与手动测试发现,结果基本一致,数组遍历各个方法的速度:传统的for循环最快,for-in最慢
for-len
>
for>
for-of>
forEach>
map>
for-in
for
循环遍历数组for...in
遍历对象for...of
遍历类数组对象(ES6)Object.keys()
获取对象属性名的集合因为for … in
语法是第一个能够迭代对象键的JavaScript语句,循环对象键({})与在数组([])上进行循环不同,引擎会执行一些额外的工作来跟踪已经迭代的属性。因此不建议使用for...in
来遍历数组
最近更新时间:2024-08-10