JS中不同数组循环方法效率对比分析是怎样的?

更新于
2026-09-28 00:40:05
1阅读来源:SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1940个文字,预计阅读时间需要8分钟。

JS中不同数组循环方法效率对比分析是怎样的?

数组方法在JavaScript发展至今已经提供了多种处理数组的函数,下面这张图概述了大部分数组方法。本文主要介绍数组遍历的方法及其各自的特点,方法众多,如何选择合适的性能?

JS中不同数组循环方法效率对比分析是怎样的?

1. for循环 - 特点:最基础,控制灵活,但代码量较多。 - 性能:中等。

2. forEach - 特点:链式调用方便,但无法break或continue。 - 性能:中等。

3. map - 特点:返回新数组,不改变原数组。 - 性能:中等。

4. filter - 特点:返回新数组,不改变原数组,筛选出符合条件的元素。 - 性能:中等。

5. some和every - 特点:用于判断数组元素是否都满足或至少有一个满足条件。 - 性能:中等。

6. reduce和reduceRight - 特点:累加器,可用于求和、最大值、最小值等。 - 性能:中等。

7. for...of循环 - 特点:直接遍历数组元素,简洁易读。 - 性能:中等。

选择哪种方法取决于具体需求和场景。以下是一些选择建议:

- 简单遍历:使用for循环或for...of循环。- 处理数组:使用map、filter等。- 判断条件:使用some或every。- 累加器:使用reduce或reduceRight。

性能方面,通常for循环和for...of循环性能较好,但实际使用中差别不大。建议根据代码可读性和易维护性来选择合适的方法。

数组的方法

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弱

for...in

任意顺序遍历一个对象的除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 **/

大部分人都喜欢用这个方法,但它的性能却不怎么好

for...of(不能遍历对象)

在可迭代对象(具有 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

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.log(array1.reduce(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循环遍历数组
  • 用for...in遍历对象
  • 用for...of遍历类数组对象(ES6)
  • 用Object.keys()获取对象属性名的集合

为何for… in会慢?

因为for … in语法是第一个能够迭代对象键的JavaScript语句,循环对象键({})与在数组([])上进行循环不同,引擎会执行一些额外的工作来跟踪已经迭代的属性。因此不建议使用for...in来遍历数组

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自由互联。

本文共计1940个文字,预计阅读时间需要8分钟。

JS中不同数组循环方法效率对比分析是怎样的?

数组方法在JavaScript发展至今已经提供了多种处理数组的函数,下面这张图概述了大部分数组方法。本文主要介绍数组遍历的方法及其各自的特点,方法众多,如何选择合适的性能?

JS中不同数组循环方法效率对比分析是怎样的?

1. for循环 - 特点:最基础,控制灵活,但代码量较多。 - 性能:中等。

2. forEach - 特点:链式调用方便,但无法break或continue。 - 性能:中等。

3. map - 特点:返回新数组,不改变原数组。 - 性能:中等。

4. filter - 特点:返回新数组,不改变原数组,筛选出符合条件的元素。 - 性能:中等。

5. some和every - 特点:用于判断数组元素是否都满足或至少有一个满足条件。 - 性能:中等。

6. reduce和reduceRight - 特点:累加器,可用于求和、最大值、最小值等。 - 性能:中等。

7. for...of循环 - 特点:直接遍历数组元素,简洁易读。 - 性能:中等。

选择哪种方法取决于具体需求和场景。以下是一些选择建议:

- 简单遍历:使用for循环或for...of循环。- 处理数组:使用map、filter等。- 判断条件:使用some或every。- 累加器:使用reduce或reduceRight。

性能方面,通常for循环和for...of循环性能较好,但实际使用中差别不大。建议根据代码可读性和易维护性来选择合适的方法。

数组的方法

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弱

for...in

任意顺序遍历一个对象的除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 **/

大部分人都喜欢用这个方法,但它的性能却不怎么好

for...of(不能遍历对象)

在可迭代对象(具有 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

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.log(array1.reduce(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循环遍历数组
  • 用for...in遍历对象
  • 用for...of遍历类数组对象(ES6)
  • 用Object.keys()获取对象属性名的集合

为何for… in会慢?

因为for … in语法是第一个能够迭代对象键的JavaScript语句,循环对象键({})与在数组([])上进行循环不同,引擎会执行一些额外的工作来跟踪已经迭代的属性。因此不建议使用for...in来遍历数组

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自由互联。