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

 更新时间:2010年10月20日 01:28:52   作者:  
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。

相关文章

  • 基于jQuery Ajax实现下拉框无刷新联动

    基于jQuery Ajax实现下拉框无刷新联动

    这篇文章主要为大家详细介绍了基于jQuery Ajax实现下拉框无刷新联动,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • jquery 单引号和双引号的区别及使用注意

    jquery 单引号和双引号的区别及使用注意

    在js中单引号和双引号都是一样的,平时使用的时候尽量用单引号,只有碰到嵌套的时候才会同时用两种引号,感兴趣的朋友可以了解下
    2013-07-07
  • 解决jQuery插件tipswindown与hintbox冲突

    解决jQuery插件tipswindown与hintbox冲突

    先扫下盲:tipswindown是jQuery的弹窗插件,可以使用url或当前页元素显示在模拟层中;hintbox是jQuery的类似Google Suggestions插件。
    2010-11-11
  • jquery delay()介绍及使用指南

    jquery delay()介绍及使用指南

    .delay()是用来在jQuery动画效果和类似队列中是最好的。但是,由于其本身的限制,比如无法取消延时——.delay(),它不是JavaScript的原生 setTimeout函数的替代品,这可能是更适合某些使用情况。
    2014-09-09
  • 基于jQuery实现网页打印功能

    基于jQuery实现网页打印功能

    这篇文章主要介绍了基于jQuery实现网页打印功能,实现的打印功能大致跟浏览器的Ctrl+P效果一样,感兴趣的小伙伴们可以参考一下
    2015-12-12
  • jquery实现简单自动轮播图效果

    jquery实现简单自动轮播图效果

    这篇文章主要为大家详细介绍了jquery实现简单自动轮播图效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • JQuery UI的拖拽功能实现方法小结

    JQuery UI的拖拽功能实现方法小结

    JQuery UI是JQuery官方支持的WebUI 代码库,包含底层交互、动画、特效等API,并且封装了一些Web小部件(Widget)。同时,JQuery UI继承了jquery的插件支持,有大量的第三方插件可以丰富JQuery UI的功能
    2012-03-03
  • jquery将json转为数据字典的实例代码

    jquery将json转为数据字典的实例代码

    这篇文章主要介绍了jquery将json转为数据字典的实例代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-10-10
  • 使用jQuery的toggle()方法对HTML标签进行显示、隐藏的方法(示例)

    使用jQuery的toggle()方法对HTML标签进行显示、隐藏的方法(示例)

    本文通过示例给大家介绍了使用jQuery的toggle()方法对HTML标签进行显示、隐藏操作的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • jQuery实现简洁的轮播图效果实例

    jQuery实现简洁的轮播图效果实例

    这篇文章主要介绍了jQuery实现简洁的轮播图效果,结合实例形式分析了jQuery的事件响应机制与页面元素动态操作相关技巧,需要的朋友可以参考下
    2016-09-09

最新评论