js中for(i in array)和for(i=0;i<array.length;i++)之间的坑

前情提要

刚刚接触到js写for循环的时候,觉得for(i in array)这种格式简直是非常直观,比三段论的for循环好写得多。直到遇到了一个坑,事情是这样的:
最开始的网页中,鉴于方便,清一色使用的是for(i in array)的格式,直到后来出于需求,在前面用Array.prototype写了一个新方法(新方法用来找出多个索引,以往的indexOf只能找出一个),后来发现之前所有写了for(i in array)的地方在最后统统多出一条undefined。

一、情况的发现:自己写了个Array.prototype到底写到哪了?

先写一个没有写新方法的array,用for…in循环console.log以下:
代码段:

  <script>
    var a = [11,12,13,14,15];
    for(i in a){
      console.log(a[i]);
    }
  </script>

控制台显示结果(前面的test.html:27表示执行代码的位置,不是console.log产生的)

test.html:27 11
test.html:27 12
test.html:27 13
test.html:27 14
test.html:27 15

此时,script中再加入Array.prototype引入新方法:

    Array.prototype.anyfunction = function(){
      var a = "这个代码段啥也没干,就占用了你的内存";
    }
    var a = [11,12,13,14,15];
    for(i in a){
      console.log(a[i]);
    }

再次显示在控制台是这个样子:

test.html:30 11
test.html:30 12
test.html:30 13
test.html:30 14
test.html:30 15
test.html:30 ƒ (){
      var a = "这个代码段啥也没干,就占用了你的内存";
    }

也就是说,他把我写的函数好像放到了数组里面。但是当我去寻找数组a.length时,两次的结果都是5,这是怎么一回事呢?

以下内容是我的一些理解和拙见,希望专业人士能够提出一些宝贵意见

二、Array也是一个Object

遥想前一阵,刚学js的时候,视频里面说: “实际上JavaScript的数据类型除了几个基本类型string、boolean、number、Null、Undefined和symbol之外,什么date啊、array啊、剩下的全都是对象。” 当时对于这句话并没有很深的理解。但是回顾这个例子,仿佛了解了一些:
既然是对象(object),那么就应该有属性和方法。拿这个array为例,他是一个对象,但是他的方法里面没有我需要的方法,我总不能去改Array构造函数内部的方法吧,怎么办呢?

三、通过prototype创建的属性方法

那就只能用prototype来创建。

Array.prototype.你需要的方法名 = function(...){...}

这个prototype到底创建了什么?我们不妨自己创建一个构造函数试试:

    function Namelist(){
      this.name1='张一';
      this.name2='李二';
      this.name3='王三';
    }
    var MyOwnNamelist = new Namelist;
    for(i in MyOwnNamelist){console.log(i)}

得到的结果是:

test.html:31 name1
test.html:31 name2
test.html:31 name3

而如果我们在创建MyOwnNamelist之前,加入一句

Namelist.prototype.name4 = '赵四';

那么结果就变成了

test.html:32 name1
test.html:32 name2
test.html:32 name3
test.html:32 name4

当我们console.log(MyOwnNamelist)时,控制台显示如下:

Namelist {name1: '张一', name2: '李二', name3: '王三'}
name1: "张一"
name2: "李二"
name3: "王三"
	[[Prototype]]: Object
		name4: "赵四"
		constructor: ƒ Namelist()
	[[Prototype]]: Object

可以看出,新添加的name4:‘赵四’,是添加到[[Prototype]]里面,但是for…in可以遍历到。这不禁让我想起我的那一堆数组,在创建一个prototype之后,数组本身的内容没有增加,但是创建的东西却都多遍历了一遍?

四、数组遍历用for…in ?!劝你别这么干!!

上网查了一下js中的in关键字:
“JavaScript中的in 操作符是对Object(对象)操作的,并不是针对数组。”
也就是说,Object.prototype实际上是添加了一个属性或者方法,添加的位置是[[Prototype]]中,而for…in会将添加进去的东西也遍历到。所以在数组中使用for…in循环的时候,数到后面,i的值会大于数组的长度,这是如果我们取 array[ i ],就会出现undefined。。。
但是for(i=0;i<array.length;i++)这种方式则是调用了.length,这是不会查到Object.prototype添加的属性方法的,因此对于数组,我建议大家老老实实,尽量不要用for…in。。。
不说了,我通篇的数组for循环用的都是for…in,我要一个一个改去了…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值