为什么我不推荐使用for..in迭代数组元素

23b9ca189726413131163fcd44602760.png

for-in语句的目的是枚举对象属性。该语句将在原型链中上升,还会枚举继承的属性,这有时是不希望的。

此外,规范不保证迭代的顺序,这意味着如果您想“迭代”一个数组对象,使用此语句您不能确定将按数字顺序访问属性(数组索引)。

例如,在 jscript (IE <= 8) 中,即使在 Array 对象上的枚举顺序也被定义为创建的属性:

 
 
var array = [];
array[2] = 'c';
array[1] = 'b';
array[0] = 'a';


for (var p in array) {
  //... p will be "2", "1" and "0" on IE
}

此外,谈到继承的属性,例如,如果您扩展Array.prototype对象(如 MooTools 那样的某些库),则该属性也将被枚举:

 
 
Array.prototype.last = function () { return this[this.length-1]; };


for (var p in []) { // an empty array
  // last will be enumerated
}

正如我之前所说的迭代数组或类似数组的对象,最好的方法是使用顺序循环,例如普通的for/while循环。

当您只想枚举对象的自身属性(未继承的属性)时,可以使用以下hasOwnProperty方法:

 
 
for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    // prop is not inherited
  }
}

有些人甚至建议直接从 from 调用该方法,Object.prototype以避免在有人hasOwnProperty向我们的对象添加命名属性时出现问题:

 
 
for (var prop in obj) {
  if (Object.prototype.hasOwnProperty.call(obj, prop)) {
    // prop is not inherited
  }
}

总结

不应该使用for..in迭代数组元素的三个原因:

  • for..in将遍历数组对象的所有自己和继承的属性,这些属性不是DontEnum;这意味着如果有人向特定的数组对象添加属性(有正当理由 - 我自己已经这样做了)或更改Array.prototype(这在应该与其他脚本一起工作的代码中被认为是不好的做法),这些属性将也被迭代;可以通过检查排除继承的属性hasOwnProperty(),但这对您在数组对象本身中设置的属性没有帮助。

  • for..in不能保证保留元素顺序。

  • 它很慢,因为您必须遍历数组对象及其整个原型链的所有属性,并且仍然只能获取属性的名称,即要获取值,需要进行额外的查找。

学习更多技能

请点击下方公众号

2174a2f57e1ea8e3bbc9a0e9f6b66472.gif

a244972e852dc98836ad9fbd4b354eb2.png

bc8aed769a81b6352d2a3070211afcb9.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值