众所周知,javascript中有两种for循环,一种是:

            var a=['this','is','a','article'],
i,
len;
for( i = 0,len = a.length;i < len; i++ ){
console.log(a[i]);
}

另一种是for in循环,形如:for (item in arr){...}

for in 循环是用在遍历一个Object的key的时候可用到的,而第一种for循环是专门用来遍历数组里面的元素,如果滥用for in循环将会导致一些不可预料的结果。

在项目中,我们有一个函数叫做:toggleSelectionAll(arr1,arr2):

var a = [],
b = [1,2,3,4,5,6];
var toggleSelectionAll = function(arr1,arr2){
if(Array.isArray(arr1) && arr1.length === arr2.length){
arr1.splice(0,arr1.length); //反选
}else if(Array.isArray(arr1)){ //全选
var item ;
for(item in arr2){
arr1.push(item);
}
}
};
toggleSelectionAll(a,b);

toggleSelectionAll的功能是实现一个类似于全选和反选的功能,但是很不幸它用了for in,所以我们就会看到全选之后的a:

["0", "1", "2", "3", "4", "5"]

这完全是错的。很快写代码的人就意识到了问题所在,原来他应该将arr1.push(item) 改成arr1.push(arr2[item]);

这一次全选之后得到了如下结果的a:

[1, 2, 3, 4, 5, 6]

这个结果是正确的。

但是又一个问题来了,这时候,有人在某段代码中加了这么一句:

Array.prototype.sayHi= function(){
   console.log('Hi~ ');
}

这时候当再次执行全选操作的时候,得到的a如下:

[1, 2, 3, 4, 5, 6, function (){
console.log('hi');
}]

什么情况??我只想要1,2,3,4,5,6啊 怎么多出来一个函数?这不仅导致a里面的数据出错,还会导致当下次反选的时候失效,因为这时候a.length !== b.length。

很明显,它就是sayHi这个函数。因为在Array.prototype中加入了这个属性,而for in循环是遍历整个数组的属性,将enumerable(表示属性是否可以被枚举)为true的属性拿出来,默认情况下,增加一个属性,那么该属性是可以被枚举的。所以很明显,就能拿到sayHi。

总的来说,这是因为对for in的滥用造成的。for in循环不应该用在遍历数组。应该用for(i=0;i<len;i++)的形式,或者用Array.forEach()的形式来做这件事。

被滥用的for in循环的更多相关文章

  1. 羽夏 Bash 简明教程(下)

    写在前面   该文章根据 the unix workbench 中的 Bash Programming 进行汉化处理并作出自己的整理,并参考 Bash 脚本教程 和 BashPitfalls 相关内容 ...

  2. python基础之条件控制与循环

    Python3 条件控制 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户 ...

  3. 深入理解JavaScript的闭包特性如何给循环中的对象添加事件

    初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...

  4. Parallel.ForEach() 并行循环

    现在的电脑几乎都是多核的,但在软件中并还没有跟上这个节奏,大多数软件还是采用传统的方式,并没有很好的发挥多核的优势. 微软的并行运算平台(Microsoft’s Parallel Computing ...

  5. 【转】Qt事件循环与线程 二

    转自:http://blog.csdn.net/changsheng230/article/details/6153449 续上文:http://blog.csdn.net/changsheng230 ...

  6. python3 第七章 - 循环语句

    为了让计算机能计算成千上万次的重复运算,我们就需要循环语句. Python中的循环语句有 while for 循环语句的执行过程,如下图: while 循环 Python中while语句的一般形式: ...

  7. 从循环添加事件谈起对JS闭包的理解

    1.引子 相信很多初学js的人,都遇到这样一种情况:想要给一堆按钮添加各自的事件,比如点击第i个按钮时,弹出i这个值.理所当然地,我们会这样写: var buttons = document.getE ...

  8. python基础-循环

    循环 循环 要计算1+2+3,我们可以直接写表达式: >>> 1 + 2 + 3 6 要计算1+2+3+...+10,勉强也能写出来. 但是,要计算1+2+3+...+10000,直 ...

  9. python笔记五(条件判断/循环/break和continue)

    一 条件判断 if <条件判断1>: <执行1> elif <条件判断2>: <执行2> elif <条件判断3>: <执行3> ...

随机推荐

  1. [转] vim自定义配置 和 在ubnetu中安装vim

    Ubuntu 12.04安装vim和配置   问题: ubuntu默认没有安装vim,出现: jyg@ubuntu:~$ vim test.cThe program 'vim' can be foun ...

  2. $.ajx的用法

    $.ajax({type:'post',//可选geturl:'action.php',//这里是接收数据的PHP程序data:'data='dsa'',//传给PHP的数据,多个参数用&连接 ...

  3. SSM——(二):easyUI的CRUD

    1.在WebContent下新建admin目录,添加index.html(用来显示user表的CRUD): 总结: 1.datagrid接收的必须是json数据: 2.使用分页插件会自动向后台传递St ...

  4. MIL 多示例学习 特征选择

    一个主要的跟踪系统包含三个成分:1)外观模型,通过其可以估计目标的似然函数.2)运动模型,预测位置.3)搜索策略,寻找当前帧最有可能为目标的位置.MIL主要的贡献在第一条上. MIL与CT的不同在于后 ...

  5. CEGUI0.8.4引入到自己工程中

    首先要确定你的CEGUI已经完全编译好,若未进行这一步请参照http://www.cnblogs.com/wenguang1996/p/5027522.html 打开VS2012新建C++工程,然后添 ...

  6. IE9浏览器中的My97日历控件刷新后无法打开问题解决办法

    解决办法如下: 1:找到WdatePicker.js 2:将$crossFrame:true 改为$crossFrame:false. 3:重启服务,刷新页面发现OK.

  7. NCreport报表控件教程:设计页眉和页脚

    一.设计页眉 一般来说页眉部分一般是用于包含标题的内容, 首先我们会添加列标签到页眉部分,标签都是简单的文本,标签项一般是用于在报表上显示一些描述信息,标签都是静态项,所以它们的值不会有变化. 添加标 ...

  8. 如何清除WebBrowser的Cookies

    var document = webBrowser1.Document; document.ExecCommand("ClearAuthenticationCache", fals ...

  9. Linux_用户级_常用命令(4):cp

    Linux_用户级_常用命令之cp 开篇语:懒是人类进步的源动力 本文原创,专为光荣之路公众号所有,欢迎转发,但转发请务必写出处! Linux常用命令第二集包含命令:cp 格式 cp  [-optio ...

  10. js,jquery获取浏览器信息

    1.js获取: 查看:window.navigator 2.jQuery获取: chrome firefox 推荐使用navigator获取userAgent然后去正则匹配 参考匹配规则:http:/ ...