JavaScript中for循环的几种写法与效率总结

前言

对于for循环,相信大家再常用不过了。但是这回说下for循环是因为看代码时我居然没有看明白一个for循环的意思,真是不应该啊。

这个for循环是这么写的:

for (var i = 0, rule; rule = rules[i++];) {
 //do something
}

这个写法是什么意思呢?后面再说,现卖个关子,这个写法我感觉还是挺好的。

for循环写法对效率的影响

说上面那段代码之前,先说一下for循环的效率问题。在接触js时关于for循环的写法和对效率影响的文章挺不少的。但总的来说对于for循环的写法有这么两种:

  1. 不写声明变量的写法:for(var i = 0;i<arr.length;i++){}
  2. 写声明变量的写法:for(var i = 0,len = arr.length;i < len;i++){}

除了for循环还有forEach() ,也有文章说forEach()效率最高,推荐用forEach()写法,那么到底哪个效率高呢?做个测试来看看吧。

测试方案

总的测试方案如下:

  1. 做一个容纳4千万的测试数组变量。
  2. 分别用两种写法的for循环和foreach对这个测试变量进行遍历。
  3. 在同一台稳定机器上,进行10次测试,最后取平均值。
  4. 测试环境:CPU:Inter(R) Core i5-3210M,RAM:12GM,system:win10(x64)

测试流程

制作测试变量

先用while循环做个测试变量出来,这个很简单,具体如下:

var testArrs = [],
 i = 0;
while(i<40000000){
 testArrs.push(i);
 i++;
}

编写相应测试函数

测量和执行时间的代码,我用的是console.time()console.timeEnd()来进行测试。

针对这个三个for循环,先做出三个函数出来,他们分别是

foreach循环测试:

function testForeach(testArrs){
 console.time('foreach');
 var newArrs = [];
 testArrs.forEach(function(i){
 newArrs.push(i);
 });
 console.timeEnd('foreach');
}

没有声明变量的for循环:

function testNoDeclare(testArrs){
 console.time('no declare');
 var newArrs = [];
 for(var i = 0;i<testArrs.length;i++){
 newArrs.push(i);
 }
 console.timeEnd('no declare');
}

有变量声明的写法

function testUseDeclare(testArrs){
 console.time('use declare');
 var newArrs = [];
 for(var i = 0,len = testArrs.length;i<len;i++){
 newArrs.push(i);
 }
 console.timeEnd('use declare');
}

执行测试函数

执行测试函数这里很简单啦,就是调用函数就可以了

testForeach(testArrs);
testNoDeclare(testArrs);
testUseDeclare(testArrs);

测试结果

经过10次测试,得到了以下结果

foreach 不写声明 写声明
2372.891ms 672.530ms 743.974ms
2431.821ms 710.275ms 805.676ms
2422.448ms 729.287ms 741.014ms
2330.894ms 730.200ms 755.390ms
2423.186ms 703.255ms 769.674ms
2379.167ms 689.811ms 741.040ms
2372.944ms 712.103ms 710.524ms
2316.005ms 726.518ms 726.522ms
2535.289ms 733.826ms 747.427ms
2560.925ms 793.680ms 817.098ms
平均值 平均值 平均值
2414.56ms 720.15ms 755.83ms

不知道结果有没有让你出乎意料呢?没想到最平常的写法效率最高,为什么?我也没想明白,谁知道就告诉我吧,但我估计写声明的写法是没有意义的。因为len = arr.length这个arr.length可能已经缓存起来了,所以我们在声明个len变量来存储是没有意义的。

最后附上全部测试代码,复制到自己的电脑上直接就可以测试了,要是有不合理的地方请告诉我吧

var testArrs = [],
 i = 0;
while(i<40000000){
 testArrs.push(i);
 i++;
}
function testForeach(testArrs){
 console.time('foreach');
 var newArrs = [];
 testArrs.forEach(function(i){
 newArrs.push(i);
 });
 console.timeEnd('foreach');
}
function testNoDeclare(testArrs){
 console.time('no declare');
 var newArrs = [];
 for(var i = 0;i<testArrs.length;i++){
 newArrs.push(i);
 }
 console.timeEnd('no declare');
}
function testUseDeclare(testArrs){
 console.time('use declare');
 var newArrs = [];
 for(var i = 0,len = testArrs.length;i<len;i++){
 newArrs.push(i);
 }
 console.timeEnd('use declare');
}
testForeach(testArrs);
testNoDeclare(testArrs);
testUseDeclare(testArrs);

for循环的特殊写法

下面说下文章刚开始说的那个我没看懂的代码,说之前先温习下再熟悉不过的for循环语法。for循环的基本语法是:

for (语句 1; 语句 2; 语句 3)
{
被执行的代码块
}
  1. 语句1:在循环(代码块)开始前执行
  2. 语句2:定义运行循环(代码块)的条件
  3. 语句3:在循环(代码块)已被执行之后执行

如果我们用for循环要输出1到10,我们可以这么写:

for(var i=0;i<10;i++){
console.log(i);
}

但是!根据上面的语法说明,我们也可以写成这样

for(var i=10;i--;){
console.log(i);
}

刚开始看的时候我也很疑惑,怎么能这么写?语句2放的是循环条件,i–是什么判断条件。其实不然,在语句2中,如果返回true循环会继续执行。在js中0,null,undefined,false,'',””作为条件判断时,其结果为false,也就说当i–到0的时候就是false,循环就终止了。

再回到文章开头的代码

for (var i = 0, rule; rule = rules[i++];) {
 //do something
}

这个rule = rules[i++]就是判断条件,当成为undefined时就会终止循环啦。所以这段代码换成普通写法就是这样的:

for(var i = 0;i < rules.length;i++){
 var rule = rules[i]
}

其实就是把判断和赋值放到一起了,一边循环一边赋值。是不是挺简单?

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用Javascript能带来一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • javaScript如何跳出多重循环break、continue

    先来说说break和continue之间的区别 摘自JavaScript高级程序设计 for(var i=0;i<10;i++){ if(i>5){ break; } } console.log(i); ---6 •当i=5和10的时候,会执行到break,并退出循环 for(var i=1;i<10;i++){ if(i>5){ continue; } num++; } console.log(num); ---4 var num=0; for(var i=1;i<10;i

  • Javascript中for循环语句的几种写法总结对比

    前言 for循环我们在js遍历对象或数组时都会有用到了,今天我们一起来看一些关于for循环的一些使用例子了,具体的操作细节如下文介绍. 一般写法如下: for(var i = 0;i< arr.length;i++) { var a = arr[i]; //... } 这就是一个常见的,正序循环的for循环.这样写的缺点大家都明白:每次都从arr里取length与i来对比,浪费性能(而且,要是arr的长度是动态变化的,就会出现死循环).改进这个循环的办法是用变量保存arr.length: for

  • jQuery的Each比JS原生for循环性能慢很多的原因

    其实查看jQuery的源代码,发现each的代码很简单,但为什么性能和原生的for循环相差几十倍呢? jQuery的each的核心代码 for (; i < length; i++) { value = callback.call(obj[i], i, obj[i]); if (value === false) { break; } } 看着很简单,但为什么会慢很多呢? 编写测试代码如下: var length=300000; function GetArr() { var t = []; fo

  • js 实现获取name 相同的页面元素并循环遍历的方法

    实例如下: <input type="hidden" name="blues" value="蓝色浏阳河之最"> <input type="hidden" name="blues" value="蓝色浏阳河之亲"> <input type="hidden" name="blues" value="蓝色浏阳河之

  • JS 循环li添加点击事件 (闭包的应用)

    废话不多说了,直接给大家贴代码了,具体代码如下所述: var aLi = document.querySelectorAll('.article-tab li'); for (var i = 0; i <= aLi.length; i++) { (function(){ var p = i aLi[i].onclick = function() { alert(p); } })(); } 以上所述是小编给大家介绍的JS 循环li添加点击事件 (闭包的应用),希望对大家有所帮助,如果大家有任何疑问

  • 原生js实现无限循环轮播图效果

    知识要点 1.实现无限循环的原理: 以偏移的距离来判断是否跳回第一张和最后一张 也可以利用循环判断图片的当前索引值 var newLeft=parseInt(list.style.left)+offset;//当前的偏移量+下一次的偏移量=新的偏移量 list.style.left=newLeft+"px";//当前的偏移值=新的偏移值 //以偏移的距离来判断是否跳回第一张和最后一张 if(newLeft>-600){ list.style.left=-3000+"px

  • JS for循环中i++ 和 ++i的区别介绍

    平时都是这样写的for循环, for(var i = 0; i < 20 ; i++){ .... } 但我看有的人这样写 for (var i = 0; i < 20 ; ++i) { .... } 这样会对for循环有什么影响? 1.在for里好像没啥区别... 但是用在赋值的时候, 就有区别了... var a = 1; var b = a++; var c = 1; var d = ++c; console.log(b,d); // 1, 2 a++ 是先应用a, 然后再自加 ++a

  • js实现为a标签添加事件的方法(使用闭包循环)

    本文实例讲述了js实现为a标签添加事件的方法.分享给大家供大家参考,具体如下: 以示例说明: 实现效果:循环为带有ml-praise样式类的a标签添加事件,并且在点击a标签后,相应的数量增加1. Html结构如下所示: <ul> <li><a href="javascript:;" class="ml-praise">数量:<span class="ding-num">100</span>

  • JavaScript中关于for循环删除数组元素内容时出现的问题

    昨天用for循环进行数组去重的时候出现的问题, 首先,用双重for循环把前一个和所有后面的元素进行比较,如果相等则删除. 但是,如果数组里面有三个以上连续相等的元素的时候,就会出现问题. var arr = [1,1,1,2,2]; for(var i=0; i<arr.length-1; i++){ for(var j=i+1; j<arr.length; j++){ if(arr[i] === arr[j]){ arr.splice(j,1); } } } document.write(&

  • JS中的三个循环小结

    一.for循环 四部曲: 1.设置初始值 var i = 0 2.设置循环执行条件 i < 5 3.执行循环体中的内容{ [循环体] } 包起来的部分 4.每一轮循环完成后都执行我们的i++累加操作 for(var i = 0;i<5;i++){ console.log(i) } break/continue:在循环体中遇到这两个关键字,循环体中的后面的代码就不在执行了 break:在循环体中,出现break,整个循环就直接的结束了,i++最后的这个累加的操作也不执行了 continue:在循

  • js实现无缝循环滚动

    本文实例为大家分享了js无缝循环滚动实现代码,供大家参考,具体内容如下 1.图片格式:260*400. 2.使用循环定时器轻松实现 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>无缝滚动</title> </head> <style type="text/css"&

随机推荐