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


Posted in Javascript onOctober 20, 2010

一,为什么不要用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 相关文章推荐
菜单效果
Oct 14 Javascript
JQUERY CHECKBOX全选,取消全选,反选方法三
Aug 30 Javascript
jQuery中:file选择器用法实例
Jan 04 Javascript
JavaScript数组常用方法
Mar 02 Javascript
js判断输入字符串是否为空、空格、null的方法总结
Jun 14 Javascript
Bootstrap select实现下拉框多选效果
Dec 23 Javascript
基于jQuery实现滚动刷新效果
Jan 09 Javascript
bootstrap table使用入门基本用法
May 24 Javascript
js实现移动端轮播图效果
Dec 09 Javascript
微信小程序实现tab左右切换效果
Nov 15 Javascript
taro小程序添加骨架屏的实现代码
Nov 15 Javascript
Vue.directive 实现元素scroll逻辑复用
Nov 29 Javascript
来自国外的14个图片放大编辑的jQuery插件整理
Oct 20 #Javascript
理解Javascript_12_执行模型浅析
Oct 18 #Javascript
理解Javascript_11_constructor实现原理
Oct 18 #Javascript
关于js中window.location.href,location.href,parent.location.href,top.location.href的用法与区别
Oct 18 #Javascript
jQuery Validation实例代码 让验证变得如此容易
Oct 18 #Javascript
jQuery 验证插件 Web前端设计模式(asp.net)
Oct 17 #Javascript
基本jquery的控制tabs打开的数量的代码
Oct 17 #Javascript
You might like
用文本文件制作留言板提示(下)
2006/10/09 PHP
php生成WAP页面
2006/10/09 PHP
php删除文本文件中重复行的方法
2015/04/28 PHP
一个完整的PHP类包含的七种语法说明
2015/06/04 PHP
PHP的命令行命令使用指南
2015/08/18 PHP
Windows 下安装 swoole 图文教程(php)
2017/06/05 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
2019/11/19 PHP
JavaScript学习笔记(十)
2010/01/17 Javascript
jquery图片延迟加载 前端开发技能必备系列
2012/06/18 Javascript
nodejs个人博客开发第二步 入口文件
2017/04/12 NodeJs
JS实现快速比较两个字符串中包含有相同数字的方法
2017/09/11 Javascript
webpack学习教程之前端性能优化总结
2017/12/05 Javascript
vue.js默认路由不加载linkActiveClass问题的解决方法
2017/12/11 Javascript
webpack源码之loader机制详解
2018/04/06 Javascript
Vue路由之JWT身份认证的实现方法
2019/08/26 Javascript
jQuery实现的移动端图片缩放功能组件示例
2020/05/01 jQuery
[01:07:20]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第二场 2月2日
2021/03/11 DOTA
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
2015/04/16 Python
深入讲解Python编程中的字符串
2015/10/14 Python
Python获取当前公网ip并自动断开宽带连接实例代码
2018/01/12 Python
TensorFlow Session会话控制&Variable变量详解
2018/07/30 Python
Python创建一个元素都为0的列表实例
2019/11/28 Python
Python使用qrcode二维码库生成二维码方法详解
2020/02/17 Python
手把手教你用纯css3实现轮播图效果实例
2017/05/04 HTML / CSS
CSS3新属性transition-property transform box-shadow实例学习
2013/06/06 HTML / CSS
HTML5移动开发图片压缩上传功能
2016/11/09 HTML / CSS
HTML5 层的叠加的实现
2020/07/07 HTML / CSS
洛杉矶生活休闲而精致的基础品牌:Mika Jaymes
2018/01/07 全球购物
岗位竞聘演讲稿
2014/01/10 职场文书
幼儿教师考核制度
2014/01/25 职场文书
九年级政治教学反思
2014/02/06 职场文书
垃圾分类的活动方案
2014/08/15 职场文书
学习党代会心得体会
2014/09/05 职场文书
《雷雨》教学反思
2016/02/20 职场文书
《夜莺的歌声》教学反思
2016/02/22 职场文书
创业分两种人:那么哪些适合创业?,哪些适合不适合创业呢?
2019/08/23 职场文书