被滥用的for in循环

众所周知,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()的形式来做这件事。

时间: 2024-10-07 05:06:08

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

python基础之条件控制与循环

Python3 条件控制 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if age >= 18: print('your age is', age) print('adult') 根据Python的缩进规则,如果if语句判断是True,就把缩进的两行print语句执行了,否则,什么

python之循环

循环 要计算1+2+3,我们可以直接写表达式: >>> 1 + 2 + 3 6 要计算1+2+3+...+10,勉强也能写出来. 但是,要计算1+2+3+...+10000,直接写表达式就不可能了. 为了让计算机能计算成千上万次的重复运算,我们就需要循环语句. Python的循环有两种,一种是for...in循环,依次把list或tuple中的每个元素迭代出来,看例子: names = ['Michael', 'Bob', 'Tracy'] for name in names: prin

for和while循环

循环Python的循环有两种: 第一种是for...in循环,依次把list或tuple中的每个元素迭代出来l = ['ni','hao','a']for name in l: print(name) 比如我们想计算1-10的整数之和,可以用一个sum变量做累加:sum = 0for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]: sum = sum + xprint(sum) 计算1-100整数和,range(101)表示从0开始小于101的所有整数.sum = 0

Python 基础之循环

循环 要计算1+2+3,我们可以直接写表达式: >>> 1 + 2 + 3 6 要计算1+2+3+...+10,勉强也能写出来. 但是,要计算1+2+3+...+10000,直接写表达式就不可能了. 为了让计算机能计算成千上万次的重复运算,我们就需要循环语句. Python的循环有两种,一种是for...in循环,依次把list或tuple中的每个元素迭代出来,看例子: names = ['Michael', 'Bob', 'Tracy'] for name in names: prin

C语言for循环

语言作为程序设计的入门语言,对于计算机专业学生的重要意义不言而喻.而循环语句是C语言学习中的一个重点与难点.本文根据学习经验,结合全国计算机等级考试三级网络技术机试真题,浅谈C语言循环语句的学习. 循环结构是结构化程序设计的基本结构之一.它和顺序结构.选择结构共同作为各种复杂程序的基本构造单元.在程序设计中许多问题需要用到循环语句,如处理 学校学生成绩:求若干个数的和:求一个数的阶乘等等.循环语句是实现程序设计中许多有规律.需要多次重复执行某些操作的最为有效的方法.循环结构是程序设 计中的一个重

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

深入理解JavaScript的闭包特性如何给循环中的对象添加事件 初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. 1.  <!DOCTYPE HTML> 2.  <html> 3.  <head&g

Java 中break和continue结合标签标示符中断循环示例详解(附源码)

臭名昭著的goto 编程语言中一开始就有goto关键词了.事实上,goto起源于汇编语言的程序控制:"若条件A成立,则跳到这里:否则跳到那里".如果阅读由编译器最终生成的汇编代码,就会发现程序控制里包含了许多跳转.(Java编译器生成它自己的"汇编代码",但是这个代码是运行在Java虚拟机上的,而不是直接运行在CPU硬件上.) goto语句是在源码级上的跳转,这使其招致了不好的声誉.若一个程序总是从一个地方跳到另一个地方,还有什么办法能识别程序的控制流程呢?自从Ed

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

初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. 1.  <!DOCTYPE HTML> 2.  <html> 3.  <head> 4.  <meta charset="utf

python 6 循环

循环 要计算1+2+3,我们可以直接写表达式: >>> 1 + 2 + 3 6 要计算1+2+3+...+10,勉强也能写出来. 但是,要计算1+2+3+...+10000,直接写表达式就不可能了. 为了让计算机能计算成千上万次的重复运算,我们就需要循环语句. Python的循环有两种,一种是for...in循环,依次把list或tuple中的每个元素迭代出来,看例子: names = ['Michael', 'Bob', 'Tracy'] for name in names: prin