JavaScript探秘:for-in循环(for-in Loops)

for-in循环应该用在非数组对象的遍历上,使用for-in进行循环也被称为“枚举”。

for-in 能枚举对象的自定义属性和原型链属性,并用hasOwnProperty()方法来只获取自定义属性。

var o ={x:1,y:2,z:3};
    for(var item in o){
        console.log(item);            //x y z
        console.log(o[item]);         //1 2 3
    }

从技术上将,你可以使用for-in循环数组(因为JavaScript中数组也是对象),但这是不推荐的。因为如果数组对象已被自定义的功能增强,就可能发生逻辑错误。另外,在for-in中,属性列表的顺序(序列)是不能保证的。所以最好数组使用正常的for循环,对象使用for-in循环。

有个很重要的hasOwnProperty()方法,当遍历对象属性的时候可以过滤掉从原型链上下来的属性。

思考下面一段代码:

01
// 对象
02
var man = {
03
   hands: 2,
04
   legs: 2,
05
   heads: 1
06
};
07

08
// 在代码的某个地方
09
// 一个方法添加给了所有对象
10
if (typeof Object.prototype.clone === "undefined") {
11
   Object.prototype.clone = function () {};
12
}

在这个例子中,我们有一个使用对象字面量定义的名叫man的对象。在man定义完成后的某个地方,在对象原型上增加了一个很有用的名叫 clone()的方法。此原型链是实时的,这就意味着所有的对象自动可以访问新的方法。为了避免枚举man的时候出现clone()方法,你需要应用hasOwnProperty()方法过滤原型属性。如果不做过滤,会导致clone()函数显示出来,在大多数情况下这是不希望出现的。

01
// 1.
02
// for-in 循环
03
for (var i in man) {
04
   if (man.hasOwnProperty(i)) { // 过滤
05
      console.log(i, ":", man[i]);
06
   }
07
}
08
/* 控制台显示结果
09
hands : 2
10
legs : 2
11
heads : 1
12
*/
13

14
// 2.
15
// 反面例子:
16
// for-in loop without checking hasOwnProperty()
17
for (var i in man) {
18
   console.log(i, ":", man[i]);
19
}
20
/*
21
控制台显示结果
22
hands : 2
23
legs : 2
24
heads : 1
25
clone: function()
26
*/

另外一种使用hasOwnProperty()的形式是取消Object.prototype上的方法。像这样:

1
for (var i in man) {
2
   if (Object.prototype.hasOwnProperty.call(man, i)) { // 过滤
3
      console.log(i, ":", man[i]);
4
   }
5
}

其好处在于在man对象重新定义hasOwnProperty情况下避免命名冲突。也避免了长属性查找对象的所有方法,你可以使用局部变量“缓存”它。

1
var i, hasOwn = Object.prototype.hasOwnProperty;
2
for (i in man) {
3
    if (hasOwn.call(man, i)) { // 过滤
4
        console.log(i, ":", man[i]);
5
    }
6
}

严格来说,不使用hasOwnProperty()并不是一个错误。根据任务以及你对代码的自信程度,你可以跳过它以提高些许的循环速度。但是当你对当前对象内容(和其原型链)不确定的时候,添加hasOwnProperty()更加保险些。

格式化的变化(通不过JSLint)会直接忽略掉花括号,把if语句放到同一行上。其优点在于循环语句读起来就像一个完整的想法(每个元素都有一个自己的属性”X”,使用”X”干点什么):

view sourceprint?
1
// 警告: 通不过JSLint检测
2
var i, hasOwn = Object.prototype.hasOwnProperty;
3
for (i in man) if (hasOwn.call(man, i)) { // 过滤
4
    console.log(i, ":", man[i]);
5
}

参考:
http://www.nowamagic.net/librarys/veda/detail/1625

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值