我在我的一个 JavaScript 文件上使用了JSLint。它抛出了错误:
for( ind in evtListeners ) {
第 41 行字符 9 处的问题:for in 的主体应包含在 if 语句中,以从原型中过滤掉不需要的属性。
这是什么意思?
首先, 永远不要 使用for in循环来枚举数组。绝不。用好老for(var i = 0; i<arr.length; i++)。
for in
for(var i = 0; i<arr.length; i++)
这背后的原因如下:JavaScript 中的每个对象都有一个名为prototype. 您添加到该字段的所有内容都可以在该类型的每个对象上访问。假设您希望所有数组都有一个很酷的新函数filter_0,该函数将过滤掉零。
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]
这是扩展对象和添加新方法的标准方法。很多图书馆都是这样做的。但是,让我们看看for in现在是如何工作的:
var listeners = ["a", "b", "c"]; for (o in listeners) { console.log(o); } //prints: // 0 // 1 // 2 // filter_0
你有看到?它突然认为 filter_0 是另一个数组索引。当然,它并不是真正的数字索引,而是for in通过对象字段进行枚举,而不仅仅是数字索引。所以我们现在枚举每个数字索引 和 filter_0. 但filter_0不是任何特定数组对象的字段,现在每个数组对象都有这个属性。
幸运的是,所有对象都有一个hasOwnProperty方法,该方法检查该字段是否真的属于对象本身,或者它是否只是从原型链继承而来,因此属于该类型的所有对象。
hasOwnProperty
for (o in listeners) { if (listeners.hasOwnProperty(o)) { console.log(o); } } //prints: // 0 // 1 // 2
请注意,尽管此代码对数组按预期工作,但您永远不应该、 从不 将for inandfor each in用于数组。请记住,它for in枚举对象的字段,而不是数组索引或值。
for each 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