JavaScript 中的for/in

JavaScript中的for/in

for/in语句也使用关键字for,但是和for循环完全是不同的一类循环。for/in循环语句的语法结构如下:
for(variable in object)
<span style="white-space:pre">	</span>statement

variable通常是一个变量,也可以是一个产生左值的表达式或者是一个通过var语句声明的变量,总之必须是一个用于赋值表达式左侧的值。
object是一个表达式,这个表达式的计算结果是一个对象。
statement是一个语句或语句块,它构成了循环的主体。

用for/in循环来遍历对象的属性:
var o = {x:1, y:2};
for(var p in o)
    console.log(p);
需要注意的是,for/in循环体中variables是一个赋值表达式左侧的值,也就是说可以是任意表达式,每次循环都会计算这个表达式,也就是说每次循环它计算的值有可能不同。
例如下面的例子,可以将对象中的属性赋值到一个数组中:
var o = {x:1, y:2};
var a = [],i=0;
for(a[i++] in o){ //语句块内什么也不做 }
在执行for/in语句的过程中,JavaScript解析器首先计算object表达式。
如果表达式为null或undefined解析器将会跳过循环,执行后续代码,不进入循环。
如果表达式是一个原始值,这原始值将会转换为对应的包装对象。
否则,object表达式本身已经是一个对象。
JavaScript会依次枚举对象的属性来执行循环。然而每次循环之前,JavaScript都会计算variables表达式的值,并将属性名(一个字符串)赋给计算后的值(就是赋值表达式的左值)。

JavaScript数组也是对象,只不过是一种特殊的对象。因此,for/in循环也可以像遍历普通对象属性一样,遍历数组索引。例如,在上面的代码之后加上这一段代码就可以遍历数组索引0,1,2:
for(var i in a) console.log(i);

其实,for/in循环并不会遍历对象的所有属性,只有"可枚举"(enumerable)的属性才会遍历到。
JavaScript核心语言所定义的内置对象的方法就是"不可枚举的"。比如,所有对象的都有toString()方法,但是for/in并不枚举toString()方法。
除了内置对象方法不可枚举之外,还有很多内置对象的属性也是“不可枚举的”。这些不可枚举的内置对象的方法和属性是原型对象上所定义的属性和方法。
比如,内置对象Number()对应的原型Number.prototype上定义方法和属性就是不可枚举的。

代码中定义的所有属性和方法都是可枚举的(ECMAScript5中可以通过特殊手段让可枚举的属性变为不可枚举,有兴趣的可以去百度一下)。
对象可以继承其它对象的属性,这些继承的自定属性也是可枚举的。也就是说,如果子类继承父类的属性是可枚举的属性,那么for/in遍历子类对象的属性时,就可以遍历该属性。
如果子类继承父类的属性是不可枚举的,那么for/in遍历子类对象的属性时,是不可枚举的。

如果for/in循环体删除了还未枚举的属性,那么这个属性将不会在枚举到。例如:
var o = {x:1, y:2};
for(var p in o){
   delete o.y;
   console.log(p); //=>只会输出 x
}
如果循环体重定义了对象新的属性,这些属性通常也不会被枚举到。例如:
var o = {x:1, y:2};
for(var p in o){ 
   o.z = 3; console.log(p); //=> x y
}
console.log(o); //=>Object{x:1,y:2,z:3}
 按通常的理解在循环体重给o定义了一个新属性z,for/in是可以遍历z属性的。但是这里for/in相当于缓存了一个原始的o对象,而在循环体中给o对象定义一个新属性,不会影响到for/in缓存的o对象。这里就这样理解吧。 
 
但是有趣的事上述代码放在IE8-中运行,for/in会遍历出在循环体中新定义的属性。IE8+和其它主流浏览器(有可能其它主流浏览器版本较低的也会和IE8-是同样的情况)不会遍历出循环体中新定义的属性。导致这样的情况出现
是每个浏览器厂商对for/in的实现不同,这里就不做深究了(因为太TM的深了,深究不过来呀!!!!)。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值