javascript for循环从入门到偏门(效率优化+奇特用法)


Posted in Javascript onAugust 01, 2012

一,for循环的基本写法
代码如下:

//例一for(var i=1;i<=10;i++) { 
alert(i); 
}

这段代码太简单了,我都不好意思拿出手。代码的执行结果是依次弹出1到10,PS:在早期的IE如IE6中,你把10改成10000,就能让用户一直点确定什么也不能干了哈哈——不要说是我出的主意。
由于这是一篇基础课程,所以我们回归正题来详细分析一下这段代码吧。
for循环的结构都是类似的,任意一个for循环都是这样的:
for(开始前;循环进行的条件;循环一次结束后做什么) {
// 主体代码
}如果仔细看一下for循环,就会发现他的一个万年不变的特点:for后的()中,永远是有且只有两个;(英文分号)!
上面的结构代码已经说明,分号的作用是用来分割for循环的执行条件。这些条件都是缺一不可的,可以为空,但位置必须留着,所以必须有两个;。
开始前:一般用来声明一些变量,如例一的var i=0,就像准备了一个篓子,里面暂时没有任何东西。工具的数量不限,你可以在for循环开始前声明100个变量,除了不好看之外,也没什么问题。
循环进行的条件:如第1个例子中的i<10,就是条件了,只有条件为真时,for循环才会进行下去,例一的条件可以看成if(i<10){//do...}。可以想象成篓子最多装10个东西,如果多了10个,就不装了,退出循环。
循环一次后做什么:例一中只是简单的给篓子里面加入一个东西,其实你还可以做很多事,毕竟循环一次不容易。
特别说明:for循环“开始前”的代码只会执行一次,不会影响整个for循环的效率,而“进行条件”与“一次结束后做什么”,你循环次数有多少,他就执行多少次,所以他们经常成为for循环性能瓶颈。
如果说for循环第1个;前是开始前做的事,那我可不可以把开始前的事情拿到for循环前面来呢?只要在开始前定义就行了嘛。答案是可以:
//例2 
var i=0; 
for(;i<10;i++) { 
alert(i); 
}

但要注意,虽然for后面的括号里“开始前”已经没有内容了,但;(分号)还在!而且必须在!
同理,既然第2个;后面的代码是一次结束后执行的,那我也可以把要执行的放在for循环后啊。如下:
//例子3 
var i=0; 
for(;i<10;) { 
alert(i); 
i++ 
}

但依然,万恶的两个;还是必须存在。
上面也就是两个基础的“偏门用法”了。。。不要说我坑爹
不过你也看到了,执行循环的条件,是不能单独提出来的,必须放在两个分号之间!前后夹击!
二,for循环的偏门写法
1,我们把例一的代码变成:
var i=0;
for(;i<10;alert(i++)) ;怎么样?这才是坑爹啊,{}都没有了!不过完全正确啊!
不过这种写法太过逆天,第2个;后面的代码最好不要多,一多起来你就不能掌握i的值了,而且因为代码混乱可能导致人为的语法错误。
适用环境:
简单的for循环操作,比如造一个元素依次是从1到1000的数字的这么一个数组,就用这招,酷就一个字。
2,深入分析
通过前面的例子我们知道,其实for循环的执行条件就是判断一个布尔值,就像这样:
var t = true; 
if(t == true) { 
alert('啊!') 
}

这个if语句没人看不懂吧,其实还可以这样写:
var t = true; 
if(t) { 
alert('啊!') 
}

效果是一样的,如果for循环的进行条件就是判断布尔值,那下面这种写法理解起来就不困难了:
var i = 10; 
for(;i;i--){ 
alert(i); 
}

这段代码的效果是依次弹出10到1(和例一反过来了)。其中for循环的进行条件简单的要死,就是个i.但根据我们前面的解说,其实条件是这样的:
if(i) { 
//do 
}

也就是i为真的情况,就继续执行循环。这个for循环的i什么时候为真呢,只要i不等于0,空字符串,undefined,null,false时,就都为真。
所以此for循环一直会执行,直到i=0,就结束了。但我们代码中不会看到0 ,迷惑新手,装B利器。
3,又一个
先看代码,来自园友snandy:
var ary = ["jack","tom","lily","andy"]; 
for(var i=0,a;a=ary[i++];){ 
console.log(a); 
}

依然是注意看for循环的进行条件:a=ary[i++]。特别注意这里是=而不是==,要是==的话循环就没法进行了。
这个条件判断很扯,我也比较晕。类似于:
if(a=b) {...} //注意是=!
此时如果b是false,那就会返回false了。
回到上面的例子中,如果i++加出了头,那ary[i++]就是false值了(null,undefined都算),所以条件就成了false,所以循环就断了。
这个例子局限很大,snandy也提到了,比如你数组中就是有个0,那也可能会导致循环终结。
4,jQuery的一个写法
function sibling( elem ) { 
var r = [], 
n = elem.parentNode.firstChild; 
for ( ; n; n = n.nextSibling ) { 
if ( n.nodeType === 1 && n !== elem ) { 
r.push( n ); 
} 
} 
return r; 
}

这是从jquery里提取的获得兄弟节点的办法,他有一个奇特的for循环。循环进行的条件是判断n是否为真。由于n一直是一个html节点,所以一直为真。而每次循环结束后都会把n的下一个节点赋给n,而当n的下一个节点没有时,n就成了false,终结循环。
小结:
从上面所有的例子可以看到,任他千奇百怪的for循环,都离不开两个;。大家想看懂一个for循环的原理,直接以;为界线分割for循环即可,一目了然。
三,for循环的效率优化
1,缓存变量
这也是最常用的效率优化办法:
var arr =[1,2,23,...,1000]; 
for(var i=0,l = arr.length;i<l;i++) { 
// 
}

由于执行条件每次循环都要判断,所以如果每次循环都从arr中读取length的话,无疑很浪费而且必然增加计算次数,造成效率浪费。
2,倒序法
比如一个数组有1000个元素,如果不考虑提取顺序,那么可以倒序循环:
var arr =[1,2,23,...,1000]; 
var i = arr.length; 
for(;i>0;i--){ 
//alert(i); 
}

为什么倒序会比顺序效率快?没有科学道理啊!其实只是因为倒序可以少用一个变量(对比下上一个例子吧),除开这点,两者没有速度差别。
3,注意跳出
不进行不必要的操作,这是基本逻辑。如有1000个li里面,有一个li上有个特殊的className,我们要找出这个li。那么,由于已经确定只有一个这样的li,我们找到这个li就应该马上跳出,break,下面的循环就没必要进行了。这样一来,由于li有999/1000的几率不是最后一个,我们肯定能节约不少计算。
其他情况请举一反三。
4,使用偏门用法
上面我介绍的偏门用法不只是写出来好看的,大部分都有节约变量节约计算的效果,能用就用,既酷又有效,何乐而不为呢?
----------------------------总结--------------------------------
我喜欢Javascript的灵活,不仅仅是因为可以用来装酷。希望在博客园学到更多的JS知识,大牛们的文章我经常看,收益良多。下面是一些我找到的在园子里的牛人,不全,没有列出来者不要诅咒我。
cloudgamer,司徒正美,汤姆大叔,snandy以及其他太低调的高手。想找他们的博客直接搜索吧。
PS:实在是喜欢博客园的插入代码功能,以后涉及到大量代码的文章都直接发博客园吧。
不要尝试下面的代码:
var arr =[1,2,23,1000]; 
for(var i=0,l = arr.length;i<l;) { 
if(arr[i]>10000) { 
i++; 
} 
}
Javascript 相关文章推荐
关于Aptana Studio生成自动备份文件的解决办法
Dec 23 Javascript
图像替换新技术 状态域方法
Jan 28 Javascript
使用jquery实现图文切换效果另加特效
Jan 20 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
Feb 04 Javascript
js实现类似MSN提示的页面效果代码分享
Aug 24 Javascript
JS实现单击输入框弹出选择框效果完整实例
Dec 14 Javascript
创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件
Jun 02 Javascript
基于bootstrop常用类总结(推荐)
Sep 11 Javascript
vue与TypeScript集成配置最简教程(推荐)
Oct 17 Javascript
vue 组件 全局注册和局部注册的实现
Feb 28 Javascript
Vue2 轮播图slide组件实例代码
May 31 Javascript
微信小程序实现订单倒计时
Nov 01 Javascript
jQuery源码中的chunker 正则过滤符分析
Jul 31 #Javascript
关于jquery ajax 调用带参数的webservice返回XML数据一个小细节
Jul 31 #Javascript
基于jquery的点击链接插入链接内容的代码
Jul 31 #Javascript
基于jQuery实现的百度导航li拖放排列效果,即时更新数据库
Jul 31 #Javascript
基于jQuery的动态增删改查表格信息,可左键/右键提示(原创自Zjmainstay)
Jul 31 #Javascript
jQuery.each()用法分享
Jul 31 #Javascript
artDialog 4.1.5 Dreamweaver代码提示/补全插件 附下载
Jul 31 #Javascript
You might like
求PHP数组最大值,最小值的代码
2011/10/31 PHP
PHP输入流php://input介绍
2012/09/18 PHP
php导入导出excel实例
2013/10/25 PHP
php根据年月获取季度的方法
2014/03/31 PHP
PHP获取本周所有日期或者最近七天所有日期的方法
2018/06/20 PHP
如何在centos8自定义目录安装php7.3
2019/11/28 PHP
js二维数组定义和初始化的三种方法总结
2014/03/03 Javascript
使用JQ来编写最基本的淡入淡出效果附演示动画
2014/10/31 Javascript
nodejs教程之环境安装及运行
2014/11/21 NodeJs
javascript实现瀑布流加载图片原理
2016/02/02 Javascript
JavaScript判断是否是微信浏览器
2016/06/13 Javascript
AngularJS动态生成div的ID源码解析
2016/08/29 Javascript
HTML5 实现的一个俄罗斯方块实例代码
2016/09/19 Javascript
vue实现简单实时汇率计算功能
2017/01/15 Javascript
JavaScript中的编码和解码函数
2017/02/15 Javascript
深入理解 JS 垃圾回收
2019/06/03 Javascript
微信小程序图片左右摆动效果详解
2019/07/13 Javascript
React中使用Vditor自定义图片详解
2020/12/25 Javascript
python逐行读取文件内容的三种方法
2014/01/20 Python
Python列表list内建函数用法实例分析【insert、remove、index、pop等】
2017/07/24 Python
python区分不同数据类型的方法
2019/10/14 Python
python二元表达式用法
2019/12/04 Python
python图片剪裁代码(图片按四个点坐标剪裁)
2020/03/10 Python
Django 多对多字段的更新和插入数据实例
2020/03/31 Python
Python 实现敏感目录扫描的示例代码
2020/05/21 Python
Python中的wordcloud库安装问题及解决方法
2020/05/27 Python
Python流程控制语句的深入讲解
2020/06/15 Python
html5 touch事件实现页面上下滑动效果【附代码】
2016/03/10 HTML / CSS
HTML5+CSS设置浮动却没有动反而在中间且错行的问题
2020/05/26 HTML / CSS
澳大利亚领先的在线美容商城:Adore Beauty
2017/04/14 全球购物
英国领先的野生鸟类食品供应商:GardenBird
2018/08/09 全球购物
莫斯科的韩国化妆品店:Sifo
2019/12/04 全球购物
Servlet方面面试题
2016/09/28 面试题
怎样客观的做好自我评价
2013/12/28 职场文书
中秋节祝酒词
2015/08/12 职场文书
2016年领导干部廉政承诺书
2016/03/24 职场文书