首先,never使用for in
循环对数组进行枚举.从不使用好的老for(var i = 0; i<arr.length; i++)
.
这背后的原因如下:JavaScript中的每个对象都有一个名为prototype
的特殊字段.您添加到该字段的所有内容都将在该类型的每个对象上进行访问.假设您希望所有数组都有一个名为filter_0
的很酷的新函数,它将使过滤归零.
Array.prototype.filter_0 = function() {
var res = [];
for (var i = 0; i < this.length; i++) {
if (this[i] != 0) {
res.push(this[i]);
}
}
return res;
};
console.log([0, 5, 0, 3, 0, 1, 0].filter_0());
//prints [5,3,1]
这是扩展对象和添加新方法的标准方法.很多图书馆都这样做.
var listeners = ["a", "b", "c"];
for (o in listeners) {
console.log(o);
}
//prints:
// 0
// 1
// 2
// filter_0
你看到了吗?它突然认为filter_0是另一个数组索引.当然,它不是真正的数字索引,而是通过对象字段枚举for in
,而不仅仅是数字索引.所以我们现在列举每一个数字索引and filter_0
.但是filter_0
不是任何特定数组对象的字段,现在每个数组对象都有这个属性.
幸运的是,所有对象都有一个hasOwnProperty
方法,它判断这个字段是否真的属于对象本身,或者它是否只是从原型链继承的,因此属于该类型的所有对象.
for (o in listeners) {
if (listeners.hasOwnProperty(o)) {
console.log(o);
}
}
//prints:
// 0
// 1
// 2
请注意,尽管这段代码对数组的作用与预期的一样,但您永远不应该使用never和for each in
来表示array.请记住,for in
枚举对象的字段,而不是数组索引或值.
var listeners = ["a", "b", "c"];
listeners.happy = "Happy debugging";
for (o in listeners) {
if (listeners.hasOwnProperty(o)) {
console.log(o);
}
}
//prints:
// 0
// 1
// 2
// happy