js中for in

上一篇相关文章:http://blog.csdn.net/yintianqin/article/details/72864020


一、谈谈js中for in 需要注意的地方

转自:http://www.2cto.com/kf/201411/348278.html

js中for in 可以遍历对象或数组的显性属性,也就是说我们自己定义的属性是可以遍历的,那些原型上默认已有的属性,例如:Object.prototype.toString、Object.prototype.hasOwnProperty 是遍历不出来的。 

for in 的基本规则如上,不过还有“坑”的地方需要我们注意: 
1、for in循环出的值不一定是按顺序的。代码如下:
var b = {3:1,42:2,11:3}
for( var key in b ){
    alert( b[key] )
}
低版本 浏览器弹窗的顺序是:1、2、3。现代浏览器弹窗的顺序是1、3、2。 
2、在原型上加扩展方法,会被for in 出来。代码如下: 
Object.prototype.test = "I am test"
var b = {"name":"txj"}
for( var key in b ){
    alert(key + " : "+ b[key])
}
我们手动加在原型上的方法,for in的时候会被遍历出来。一般我们遍历对象并不需要其原型的属性,所以遍历时最好Object.prototype.hasOwnProperty方法进行判断。 
3、在实例中定义原型中已有的方法,浏览器for in 情况不一致。代码如下:
var b = {"name":"txj"}
b.toString = function(){ alert("I am toString") }
for( var key in b ){
    alert(key + " : "+ b[key])
}
我们给b实例加了一个原型上已有的方法toString。现代浏览器能循环出toString 低版本浏览器却不能。所以给实例定属性名时,不要和原型已有的一致。 
4、各浏览器循环出的属性顺序不同。代码与2中的一样: 
Object.prototype.test = "I am test"
var b = {"name":"txj"}
for( var key in b ){
    alert(key + " : "+ b[key])
}
现代浏览器先循环实例中的属性,再循环原型中的属性。低版本浏览器相反。 
这让我想到了jQuery对$.isPlainObject()方法实现的一段代码: 
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
var key
for ( key in obj ) {}
return key === undefined || hasOwn.call( obj, key );
它这里说如果一个对象的最后一个属性是实例自己的属性,那么所有的属性都是实例自己的属性。这对低版本浏览器来说应该是不对的。所以jquery后来又加了如下代码修复: 
// Support: IE<9
// Handle iteration over inherited properties before own properties.
if ( support.ownLast ) {
    for ( key in obj ) {
        return hasOwn.call( obj, key );
    }
}

二、浅谈javascript中for in 和 for each in的区别

转自:http://www.jb51.net/article/64670.htm

两个的作用都用来遍历对象,但为什么有了for in语句了还要for each in语句呢,后来看了下for each in开发的文档,for each in是作为E4X标准的一部分在javascript 1.6中发布的,而且它不是ECMAScript标准的一部分

区别一:

        for in是javascript 1.0 中发布的。
        for each in是作为E4X标准的一部分在javascript 1.6中发布的,而它不是ECMAScript标准的一部分。
        这将意味着存在各种浏览器的兼容性问题。for each in,对很多浏览器都不支持的。例如是不支持IE6,IE7,IE8等浏览器的。

区别二:

    例:  var 长方形= {  高:"15",  宽:"25"  };


1
2
3
for ( var i in 长方形){
   alert( i + "," + 长方形[i] );
}

    结果依次是:  高,15  ;    宽,25 ;


1
2
3
for each ( var i in 长方形){
   alert( i + "," + 长方形[i] );
}

    结果依次是: 15, undefined ;    25, undefined;

    两种遍历方法的变量i的值是不一样的,for each in无法获得对象的属性名,只能获取到属性值。

    最后总结一下使用建议:

    (1)遍历普通数组,建议使用原生的遍历方法for,不要贪图方便,因为for in 和for each in均存在浏览器的兼容问题,不能保证它们对数组的遍历顺序(如果对顺序的不作要求的话,可以使用for in ,但本人不建议),有兴趣话,可以阅读的下一篇文章《关于js中for in的缺陷浅析》。

    (2)遍历对象,由于for没办法提供理想的遍历,因而只能选择其他方法。这里建议使用for in ,从上面讲解的区别,for in比for each 更具优势,for in能获取索引和属性值,而for each只能获取属性值,而且for each在很多低版本的浏览器是不支持。


不要使用 for...in 遍历数组。在这种情况下最好使用传统的 for 循环。

原因是 for...in 把数组看做一个对象, 所以一些属性,像 indexOf 或者 length 可能会被包含在循环中。正常的 for 循环只处理数字键,所以避免了这个问题。

另一方面,在遍历平面对象时也可能出现不必要的属性(比如添加到对象的原型的属性)。你也可以用过用以下的 for...in 循环方式来解决这个问题:

var obj = { ... };
for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    var item = obj[prop];
    ...
  }
}

需要注意的是,你仍然不该在遍历数组时使用for...in





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值