search

Home  >  Q&A  >  body text

javascript - js foreach比for多出两个undefined

var Ele = document.getElementsByTagName("iframe");
/* 	for(var i in Ele){
	alert(Ele[i].src);
	}  */
	for(var i=0;i<Ele.length;i++){
	alert(Ele[i].src);
	}

注释里运行的结果会多alert两次undefined,为什么呢

PHP中文网PHP中文网2818 days ago767

reply all(3)I'll reply

  • ringa_lee

    ringa_lee2017-04-10 12:45:37

    foreach是取一个对象上的所有属性,而非遍历数组,例如如下代码:

    var prop, obj = { a: "a", b: "b" };
    obj[0] = "c";
    for (prop in obj) {
        console.log(prop + "=" + obj[prop]);
    }

    输出是类似:0=c, a=a, b=b

    楼主的foreach实际遍历的是一个NodeList对象而非纯数组,此对象上有一个item方法和一个length属性(由W3C DOM Spec - Interface NodeList定义),在代码循环中追加log可以看出:

    var Ele = document.getElementsByTagName("iframe");
    for (var i in Ele) {
        console.log(i + "=" + Ele[i]);
    }

    输出应该是类似:0=xxx,1=xxx...length=?,item=function() {...},后面两个一个是int一个是function,src属性自然为空

    最后建议遍历数组还是尽量用for,foreach有风险

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 12:45:37

    首先两次undefined的根本原因在于用for in遍历时,遍历到了两个不存在src属性的属性。
    举个例子:

    ​<p class="p1"></p>
    <p class="p2"></p>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
    var ps = document.getElementsByTagName('p');

    console.dir(ps)我们可以得到:

    NodeList[2]
    	0: HTMLpElement
    	1: HTMLpElement
    	length: 2
    	__proto__: NodeList
    		constructor: function NodeList() { [native code] }
    		item: function item() { [native code] }
    		__proto__: Object

    上面的 ps 是一个NodeList 对象,也是一个伪数组。即本质上是对象但也有数组的一些特性,比如有length属性,可以用索引遍历但没有数组的push,shift等函数。

    而 NodeList 对象有两个属性:
    length:返回节点列表中的节点数目
    item():返回节点列表中处于指定的索引号的节点。

    for in遍历时遍历到了length,item()方法,因为没有上面的src属性,因此返回undefined。
    而for(var i=0,len=ps.length;i<len;i++)遍历只遍历了前面length个属性。

    最后,不要用for in来遍历数组,除非有意为之。

    reply
    0
  • 黄舟

    黄舟2017-04-10 12:45:37

    感谢二位的回答!看来得好好啃一啃基础了

    reply
    0
  • Cancelreply