JSLint 错误“for in 的主体应包装在 if 语句中”是什么意思?
我在我的JavaScript文件上使用JSLint。它抛出了错误:
for( ind in evtListeners ) {
第 41 行第 9 个字符处的问题:for in 的正文应包装在 if 语句中,以从原型中筛选不需要的属性。
这是什么意思?
我在我的JavaScript文件上使用JSLint。它抛出了错误:
for( ind in evtListeners ) {
第 41 行第 9 个字符处的问题:for in 的正文应包装在 if 语句中,以从原型中筛选不需要的属性。
这是什么意思?
首先,永远不要使用循环来枚举数组。从不。使用好旧的.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]
这是扩展对象和添加新方法的标准方法。很多库都这样做。但是,让我们看看现在是如何工作的: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
for (o in listeners) {
if (listeners.hasOwnProperty(o)) {
console.log(o);
}
}
//prints:
// 0
// 1
// 2
请注意,尽管此代码对数组按预期工作,但您永远不应该、永远不要使用 和 数组。请记住,枚举对象的字段,而不是数组索引或值。for in
for each in
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
Jslint的作者道格拉斯·克罗克福德(Douglas Crockford)曾多次写过(并说过)这个问题。在他的网站的这个页面上有一个部分涵盖了这一点:
用于声明
for 类语句应具有以下形式:
for (initialization; condition; update) { statements } for (variable in object) { if (filter) { statements } }
第一种形式应该与数组和预定迭代次数的循环一起使用。
第二种形式应与对象一起使用。请注意,添加到对象原型的成员将包含在枚举中。明智的做法是使用 hasOwnProperty 方法来区分对象的真正成员,从而进行防御性编程:
for (variable in object) { if (object.hasOwnProperty(variable)) { statements } }
Crockford在YUI剧院也有一个视频系列,他在其中谈到了这一点。Crockford关于javascript的系列视频/谈话是你必须看看你是否对javascript有点认真。