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


Posted in Javascript onFebruary 03, 2017

前言

对于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能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
30个精美的jQuery幻灯片效果插件和教程
Aug 23 Javascript
使用javascript控制cookie显示和隐藏背景图
Feb 12 Javascript
JS实现简单路由器功能的方法
May 27 Javascript
javascript 判断页面访问方式电脑或者移动端
Sep 19 Javascript
第一次接触Bootstrap框架
Oct 24 Javascript
详解Vue.js入门环境搭建
Mar 17 Javascript
vue 和vue-touch 实现移动端左右导航效果(仿京东移动站导航)
Apr 22 Javascript
AngularJs实现聊天列表实时刷新功能
Jun 15 Javascript
vue.js移动端app实战1:初始配置详解
Jul 24 Javascript
Vue组件全局注册实现警告框的实例详解
Jun 11 Javascript
JavaScript中的&quot;=、==、===&quot;区别讲解
Jan 22 Javascript
详解一个小实例理解js原型和继承
Apr 24 Javascript
jquery实现刷新随机变化样式特效(tag标签样式)
Feb 03 #Javascript
漂亮实用的页面loading(加载)封装代码
Feb 03 #Javascript
理解javascript中的Function.prototype.bind的方法
Feb 03 #Javascript
JavaScript数组复制详解
Feb 02 #Javascript
常用jQuery选择器汇总
Feb 02 #Javascript
JavaScript优化以及前段开发小技巧
Feb 02 #Javascript
JavaScript字符集编码与解码详谈
Feb 02 #Javascript
You might like
做个自己站内搜索引擎
2006/10/09 PHP
一个简单php扩展介绍与开发教程
2010/08/19 PHP
PHP执行SQL文件并将SQL文件导入到数据库
2015/09/17 PHP
PHP实现伪静态方法汇总
2016/01/13 PHP
Linux系统中为php添加pcntl扩展
2016/08/28 PHP
PHP字符串逆序排列实现方法小结【strrev函数,二分法,循环法,递归法】
2017/01/13 PHP
一个非常实用的php文件上传类
2017/07/04 PHP
Jquery Ajax学习实例 向页面发出请求,返回XML格式数据
2010/03/14 Javascript
javascript onmouseout 解决办法
2010/07/17 Javascript
JavaScrip单线程引擎工作原理分析
2010/09/04 Javascript
js原生态函数中使用jQuery中的 $(this)无效的解决方法
2011/05/25 Javascript
setTimeout()与setInterval()方法区别介绍
2013/12/24 Javascript
轻松创建nodejs服务器(1):一个简单nodejs服务器例子
2014/12/18 NodeJs
倾力总结40条常见的移动端Web页面问题解决方案
2016/05/24 Javascript
详解微信第三方小程序代开发
2017/06/23 Javascript
使用 jQuery 实现表单验证功能
2017/07/05 jQuery
JS实现的文字间歇循环滚动效果完整示例
2018/02/13 Javascript
js 将线性数据转为树形的示例代码
2019/05/28 Javascript
DatePickerDialog 自定义样式及使用全解
2019/07/09 Javascript
浅谈layui使用模板引擎动态渲染元素要注意的问题
2019/09/14 Javascript
解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题
2020/08/03 Javascript
Vue如何实现变量表达式选择器
2021/02/18 Vue.js
玩转python爬虫之正则表达式
2016/02/17 Python
Python实现pdf文档转txt的方法示例
2018/01/19 Python
详解Python 切片语法
2019/06/10 Python
Python基于BeautifulSoup和requests实现的爬虫功能示例
2019/08/02 Python
使用虚拟环境打包python为exe 文件的方法
2019/08/29 Python
python关于调用函数外的变量实例
2019/12/26 Python
Trip.com香港网站:Ctrip携程旗下,全球最大的网上旅游社之一
2016/08/01 全球购物
Easy Spirit官网:美国休闲鞋履中的代表品牌
2019/04/12 全球购物
初中生期末评语大全
2014/04/24 职场文书
团支部建设方案
2014/05/02 职场文书
四风剖析查摆对照检查材料思想汇报
2014/09/24 职场文书
《草船借箭》教学反思
2016/02/23 职场文书
十大最强岩石系宝可梦,怪颚龙实力最强,第七破坏力很强
2022/03/18 日漫
“鬼灭之刃”热度不减,其成功背后的原因是什么?
2022/03/22 日漫