欢迎您访问我爱IT技术网,今天小编为你分享的javascript教程:【Javascript技巧之不要用for in语句对数组进行遍历】,下面是详细的讲解!
Javascript技巧之不要用for in语句对数组进行遍历
一,为什么不要用for in语句
jqModal这个jquery插件估计很多人都使用过,在jqModal源码内部,有一个函数为hs,其中有个嵌套循环如下,
for(var i in {jqmShow:1,jqmHide:1})
for(var s in this[i])
if(H[this[i][s]])
H[this[i][s]].w[i](this);
return F;
}
第一个for in遍历的目标是个匿名对象,没有问题。
第二个for in遍历,根据上下文确认this[i]是一个数组对象(Array)。
很多JS先驱者都告诫过我们不要对数组对象使用for in语句进行遍历,原因除了性能外,还有可能产生意料之内的bug。不听先人言,吃亏在眼前呵呵。
今天偶拿jqModal为例,说明下这种bug到底什么时候会出现,当引以为戒。
二,问题重现
关键词:原生Array类、扩展Array类
for in 语句对数组对象进行遍历潜在的bug在于:如果原生Array类被其他的js脚本库进行了原型扩展(比如多加一个toJSON方法即Array.prototype.toJSON=xxxx),那么用for in遍历扩展后的Array对象的逻辑将与遍历原生Array对象的逻辑发生差异。
举个简单的例子,
var x=[1];
for(var s in x){
alert(s);
};
按常理,如果Array是原生js类,上面语句应该只执行一次alert方法,且s为数组的索引0。但是,如果Array类被扩展了,多了一个toJSON方法,那么上面的语句将执行两次alert,第一次s为索引0,第二次s为方法名'toJSON'。
如果你设计的代码的逻辑以原生Array类为基准,在某一天你的同事在页面里面引用了一个第三方的JS库,这个库又恰好扩展了Array类,结果将难以想象,很有可能原来的代码逻辑将不再成立。
关于这种扩展原生JS类的库,很有名的一个就是prototype.js,它给Array类扩展了很多方法诸如toJSON,each等等。我现在明白为啥jquery的创始人曾经对prototype火大了(不少人因为特殊原因在一个页面里用jquery同时又用prototype,会有很多意料之外的冲突问题,仅仅一个noConflict是无法解决的)。另外,jqModal的作者如果看得懂我这篇文章估计也会对埋怨prototype,说:“我用for in对数组遍历是不明智的,但是更该死的还是prototype。。。”
如上所述,如果你在用jqModal,同时因为别的原因在用prototype,恭喜你中招了。冲突将导致jqModal的弹框在ie6、ie7下面将无法利用closeClass设置的按钮进行自动关闭。跟踪调试代码你将发现,异常的地方就在本文开头提到的hs方法的for in 循环中。。。
三,解决问题
遍历数组的地方,用for var 语句代替for in。
关于Javascript技巧之不要用for in语句对数组进行遍历的用户互动如下:
相关问题:跪求详解~java中foreach方法来遍历数组的详解,主...
答:增强for(part1:part2){part3}; part2中是一个数组对象,或者是带有泛性的集合. part1定义了一个局部变量,这个局部变量的类型与part2中的对象元素的类型是一致的. part3当然还是循环体. foreach语句是java5的新特征之一,在遍历数组、集合方面,fo... >>详细
相关问题:JS中for...in 语句用于对数组或者对象的属性进行循...
答:是的 for(variable in object) object为null、undefined,javascript会跳过循环执行后面的代码,在ECMAScript3中可能会抛出类型错误异常 object为原始值,会转换为与之对应的包装对象 若为对象类型,javascript会依次枚举对象的属性来执行循环,... >>详细
相关问题:for语句和数组
答:for是个计数循环,就是循环的次数是固定的。它的格式是: for(init; condition; next) { 循环做的事情; } 在这里init是初始条件,condition是个条件,满足这个条件就循环。next就个记数变化的量。 比如我们要给数组元素赋偶数: my_array=new Ar... >>详细
- 【Array】js中更短的 Array 类型转换-类型转换
- 【ExtJs】ExtJs 表单提交登陆实现代码-表单提交-
- 【Ajax】jQuery 学习第六课 实现一个Ajax的TreeVi
- 【extjs】extjs每个组件要设置唯一的ID否则会出错
- 【focus】JavaScript使用focus()设置焦点失败的解
- 【bootstrap3】基于bootstrap3和jquery的分页插件
- 【datagrid】jQuery easyui datagrid动态查询数据
- 【ajax】js获取通过ajax返回的map型的JSONArray的
- 【hover】jQuery控制图片的hover效果(smartRollo
- 【ajax更新数据库】ajax异步刷新实现更新数据库-
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
