众所周知,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. C语言pow函数编写

    C语言pow函数编写 #include<stdio.h> double chaoba(double f,double q); //声明自定义函数 void main(void) { dou ...

  2. CentOS 7 启动、重启、chkconfig等命令已经合并为systemctl

    CentOS 7系统服务启动.重启.设置服务启动项命令以合并为,systemctl . 现在用service 或/etc/init.d/命令,重启,重新启动,停止等没效果,因为命令合并为systemc ...

  3. S3C2440上RTC时钟驱动开发实例讲解(转载)

    嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 共享资源,欢迎转载:http:/ ...

  4. .net实现webservice简单实例分享

    原理:WebService是一个SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平台,可以实现不同的语言间的相互调用,通过Internet进行基于Http协议的网络应用间的交互.作用:主要用 ...

  5. js基础教程四之无缝滚动

    前面学习了相关js的一些基础知识,这节主要针对定时器作综合运用: 无缝滚动-基础 效果演示: *物体运动基础 *让div移动起来 *offsetLeft的作用 *用定时器让物体连续移动 <sty ...

  6. 浅谈JDBC编程

    一.概述 1.为什么要用JDBC 数据库是程序不可或缺的一部分,每一个网站和服务器的建设都需要数据库.对于大多数应用程序员(此处不包含数据库开发人员)来说,我们更多的不是在DBMS中对数据库进行操纵, ...

  7. 《zw版·Halcon入门教程与内置demo》

    <zw版·Halcon入门教程与内置demo> halcon系统的中文教程很不好找,而且大部分是v10以前的版本. 例如,QQ群: 247994767(Delphi与halcon), 共享 ...

  8. jquery.serialize

    jQuery - serialize() 方法 serialize() 方法通过序列化表单值,创建 URL 编码文本字符串. serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交 ...

  9. c#的逻辑运算符重载

    不光是C++,实际上C#中同样可以对操作符重载.如:namespace Com.EVSoft.Math{  public class Vector3:BaseObject  {    ...    . ...

  10. ios webView 放大网页解决/input 获得焦点focus 网页放大 解决

    新手遇到的问题: 终于找到原因,各种HTML viewport 都试过 setScalePageToFit 也试过,webViewDidFinishLoad加JS代码,动态算webView.scrol ...