就for循环VS for-in循环
这种模式的问题在于每次循环迭代的时候都要访问数据的长度。这样会使代码变慢,特别是当myarray不是数据,而是HTML容器对象时。
HTML容器是DOM方法返回的对象,如:
document.getElementsByName()
document.getElementsByClassName()
document.getElementsByTagName()
还有很多其他HTML容器,他们在DOM标准以前就引入了,并一直使用至今。包括(除此之外还有很多):
docuement.images
页面上所有的IMG元素。
document.links
页面的A元素
document.forms
所有的froms。
document.forms[0].elements
页面上第一个from内的所有字段
容器的麻烦在于他们在document(HTML页面)下是活动的查询。也就是说,每次访问任何容器的长度时,也就是在查询活动的DOM操作时非常耗时的。
这就是为什么好的for循环模式是将已经遍历过的数组(或容器)的长度缓存起来。如以下代码所示。
for (var i = 0; max = myarray.length; i++) {
//对myarray[i]进行处理
}
这种方式下,对长度的值只提取一次,但应用到整个循环中。
在所有的浏览器中,通过将HTML容器上需要遍历的次数缓存起来都会大大提高速度。其中在Safari 3中速度会提高两倍,而在Ie7种会提高170倍。
注意,当要在循环中修改容器时(例如新增一个DOM元素),需要修改容器的长度。
function looper() {
var i = 0,
max,
myarray = [];
//...
for (i = 0, max = myarray.length; i < max; i++) {
//处理myarray[i]
}
}
这种模式的好处在于一致性,因为他贯穿了单一变量的模式。至缺陷在于创建代码时粘贴和复制整个循环比较麻烦。例如,如果要从一个函数复制循环至另一个函数,必须确保能将i和max携带至新函数中(如果这几个量在原函数中不再需要,则很可能会删掉他们了)。
对于循环的最后一个改进是,用i++代替以下两种表达式:
i = i + 1;
i += 1;
JsJLint推荐这样做,原因++和--提倡“excessive trickiness”,如果不同意这种说法,
可以将JsLint操作的plusplus设成flase(默认为真)。
for 模式中的两个变量引出了一些细微操作,原因是:
1.使用了最少的变量(而非最多)
2.逐步渐至0,这样通常更快,因为同0比较比同数组的长度比较,或同非0数组比较更有效率。
第一个修改后的模式是:
var i, myarray = [];
//注意要添加;号,这个是省略了第三个参数而已
for (i = myarray.length; i--;) {
//处理myarray[i]
}
第二个使用while循环:
var myarray = [],
i = myarray.length;
while (i--) {
//处理myarray[i]
}
for-in循环
for-in 循环应该用来遍历非数组对象。使用for-in循环也被称为枚举(enumeration);
从技术上来说,也可以使用for-in循环来遍历数组 (因为JavaScript中,数组也是对象),但是不推荐用户这样使用,因为当该数组对象已经被自定义函数扩大后,这样做有可能会导致逻辑上的错误。因此推荐使用正常的for循环来处理数组,并使用for-in循环来处理对象。
请考虑如下例子:
//对象
var man = {
hands: 2,
legs: 2,
heads: 1
};
//代码的其他部分
//将一个方法添加到所有对象上
if (typeof Object.prototype.clone === "undefined") {
Object.prototype.clone = function() {};
}
在本例子中,使用文本定义了一个简单的名为man的对象。在man对象定义前面或者后面的其他位置,使用了一个名为clone()的所有的方法来增加Object的原型。该原型链式活动的,这也就意味着所有的对象都会自动获取针对新方法的访问。为了避免在枚举man的方法时枚举出clone()方法,需要调用hasOwnPorperty()函数来过滤该原型属性。如果不使用过滤函数来进行过滤,将会显示出clone(),这在大多数情况下是不希望得到的结果。
//1.
//for-in循环
for (var i in man) {
if (man.hasOwnProperty(i )) {
console.log(i, ":", man[i]);
}
}
/
hands: 2
legs: 2
heads: 1
/
//2.
//反模式:
//不使用hasOwnProperty()进行检查后使用for-in循环的结果
for (var i in man) {
console.log(i, ":", man[i]);
}
/
控制台中的结果
hands: 2
legs: 2
heads: 1
clone: function()
/
另外一种使用hasOwnPorperty()的模式是在Object.ptototype中调用该函数,如下所示:
for (var i in man) {
if (Object.prototype.hasOwnProperty.call(man, i )) { //过滤
console.log(i, ":", man[i]);
}
}
在使用hasOwnProperty对man对象进行精炼后,可以有效的避免命名冲突,也可以使用一个本地变量来缓存比较长的属性如下所示:
var i,
hasOwn = Object.prototype.hasOwnProperty;
for (i in man) {
if (hasOwn.call(man, i)) { //过滤
console.log(i, ":", man[i]);
}
}
就for循环VS for-in循环的更多相关文章
- sqlserver中的循环遍历(普通循环和游标循环)
sql 经常用到循环,下面介绍一下普通循环和游标循环 1.首先需要一个测试表数据Student
- Javascript基础系列之(六)循环语句(for循环)
如果您希望一遍又一遍地运行相同的代码,并且每次的值都不同,那么使用循环是很方便的. document.write(cars[0] + "<br>"); document ...
- Oracle PL/SQL中的循环处理(sql for循环)
今天来说下Oracle中的循环迭代处理,因为从自己的博客统计中看到,不少网友都搜索了关键字"SQL FOR循环",所以打算在这里说下个人的理解. PL/SQL也和我们常用的编程语言 ...
- 循环嵌套,while循环,穷举迭代循环
一.循环嵌套 简单的就是说,在一个for循环里嵌入多个小for循环. 其中,在打矩形.三角形和乘法口诀表之类的题目中,大for循环一般表示的是行数,其余的小for循环式每一行中的内容. 二.while ...
- jQuery中each的用法之退出循环和结束本次循环
jQuery中each的用法之退出循环和结束本次循环 jQuery中each类似于javascript的for循环 但不同于for循环的是在each里面不能使用break结束循环,也不能使用conti ...
- 慕课网-安卓工程师初养成-4-14 Java 循环语句之多重循环
来源:http://www.imooc.com/code/1497 循环体中包含循环语句的结构称为多重循环.三种循环语句可以自身嵌套,也可以相互嵌套,最常见的就是二重循环.在二重循环中,外层循环每执行 ...
- Java 循环语句之多重循环
循环体中包含循环语句的结构称为多重循环.三种循环语句可以自身嵌套,也可以相互嵌套,最常见的就是二重循环.在二重循环中,外层循环每执行一次,内层循环要执行一圈. 如下所示: 例如:使用 * 打印长方形: ...
- §12 循环101-while循环
§12 循环101-while循环 While和for具有一定的可替换性.语法如下: while test body continue终止当次循环,break退出整个循环. 注意while之后要用 ...
- swift基本用法-for循环遍历,遍历字典,循环生成数组
// Playground - noun: a place where people can play import UIKit //--------------------------------- ...
- JavaScript循环之for/in循环
今天学到了JavaScript的语句篇.同其他常见编程语言如C.Java等一样,JavaScript中的语句包含:①表达式语句②复合语句和空语句③声明语句④条件语句⑤循环语句⑥跳转语句,当然JavaS ...
随机推荐
- SVN回退版本
执行svn up 命令 保证当前本地版本是最新的版本. svn up 执行svn log 命令,查看历史修改,确定需要回复的版本,如果想要对比2个不同版本的文件差异 可以使用命令 svn diff - ...
- Apache Ignite 学习笔记(四): Ignite缓存冗余备份策略
Ignite的数据网格是围绕着基于内存的分布式key/value存储能力打造的.当初技术选型的时候,决定用Ignite也是因为虽然同样是key/value存储,它有着和其他key/value存储系统不 ...
- kubeadm安装kubernetes 1.13.1集群完整部署记录
k8s是什么 Kubernetes简称为k8s,它是 Google 开源的容器集群管理系统.在 Docker 技术的基础上,为容器化的应用提供部署运行.资源调度.服务发现和动态伸缩等一系列完整功能,提 ...
- MSSQL批量写入数据方案
近来有一个项目Feature需要有批量写入数据的场景,正巧整理资料发现自己以前也类似实现的项目,在重构的同时把相关资料做了一个简单的梳理,方便大家参考. 循环写入(简单粗暴,毕业设计就这样干的)(不推 ...
- Android中应用contentprovider来创建数据库的一些步骤
http://blog.csdn.net/xiaodongvtion/article/details/7865669 1:首先创建一个xxprovider的class,它是extendscontent ...
- PowerTeam--Alpha阶段个人贡献分及转会人员
PowerTeam--Alpha阶段个人贡献分 我们的团队共有6人,总分300分. 经团队成员通过个人申请以及组内投票的方式,最终的等级评定如下面的等级评定矩阵所示: β1 β2 β3 γ1 γ2 ...
- LINUX内核分析第一周学习总结——计算机是如何工作的
LINUX内核分析第一周学习总结——计算机是如何工作的 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/ ...
- “数学口袋精灵”App的第一个Sprint计划(总结)
“数学口袋精灵”App的第一个Sprint计划 ——11.20 星期五(第十天)第一次Sprint计划结束 第一阶段Sprint的目标以及完成情况: 时间:11月11号~11月20号(10天) ...
- 四则运算生成程序——GUI支持和部分功能改进
项目成员:张金生 张政 工程地址: https://coding.net/u/jx8zjs/p/paperOne/git ssh://git@git.coding.net:jx8zjs/pap ...
- clear & file input & reset & file input
clear & file input & reset & file input Clear <input type="file"> docume ...