作家
登录

Javascript技巧之不要用for in语句对数组进行遍历

作者: 来源:www.28hudong.com 2013-03-30 01:15:19 阅读 我要评论

一,为什么不要用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。

  推荐阅读

  基本jquery的控制tabs打开的数量的代码

复制代码 代码如下: var tabcount = $('#tabs').tabs('tabs').length;修改addTab 方法为:function addTab(subtitle, url, icon) { var tabcount = $('#tabs').tabs('tabs').length; if (tabcount <= 5) { if (!$(>>>详细阅读


本文标题:Javascript技巧之不要用for in语句对数组进行遍历

地址:http://www.17bianji.com/kaifa2/JS/25586.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)