我在我的JavaScript文件上使用了JSLint。它抛出错误:
for( ind in evtListeners ) {
第41行字符9的问题:for in的主体应该是 包装在if语句中以过滤不需要的 原型中的属性。
这是什么意思?
我在我的JavaScript文件上使用了JSLint。它抛出错误:
for( ind in evtListeners ) {
第41行字符9的问题:for in的主体应该是 包装在if语句中以过滤不需要的 原型中的属性。
这是什么意思?
当前回答
当然,这样说有点极端
...永远不要使用for in循环to 枚举数组。从来没有。使用 (var I = 0; 我< arr.length;我+ +)
?
道格拉斯·克罗克福德节选中的这部分值得强调
…第二种形式应该用with 对象……
如果你需要一个关联数组(又名哈希表/字典),其中键是命名的,而不是数字索引,你将不得不实现它作为一个对象,例如var myAssocArray = {key1: "value1", key2: "value2"…};
In this case myAssocArray.length will come up null (because this object doesn't have a 'length' property), and your i < myAssocArray.length won't get you very far. In addition to providing greater convenience, I would expect associative arrays to offer performance advantages in many situations, as the array keys can be useful properties (i.e. an array member's ID property or name), meaning you don't have to iterate through a lengthy array repeatedly evaluating if statements to find the array entry you're after.
无论如何,也感谢JSLint错误消息的解释,我将使用'isOwnProperty'检查现在通过我的无数关联数组交互!
其他回答
只是添加到for in/for/$的主题。每一个,我添加了一个jsperf测试用例使用$。每个vs for在:http://jsperf.com/each-vs-for-in/2
不同的浏览器/版本处理它的方式不同,但似乎$。每一种都是性能上最便宜的选择。
如果你使用for in来遍历一个关联数组/对象,知道你在寻找什么,忽略其他一切,使用$。每一个如果你使用jQuery,或者只是在(然后休息;一旦你到达了你所知道的最后一个元素)
如果你在一个数组中迭代每个键对来执行一些事情,如果你不使用jQuery,应该使用hasOwnProperty方法,并使用$。每一个如果你使用jQuery。
如果你不需要关联数组,请使用for(i=0;i<o.length;i++)。哈哈,chrome比for in或$.each快97%
首先,永远不要使用for in循环来枚举数组。从来没有。使用good old for(var i = 0;我< arr.length;我+ +)。
这背后的原因如下:JavaScript中的每个对象都有一个称为prototype的特殊字段。您添加到该字段的所有内容都将在该类型的每个对象上可访问。假设您希望所有数组都有一个很酷的名为filter_0的新函数,该函数将过滤掉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是另一个数组索引。当然,它并不是真正的数字索引,而是用于枚举对象字段,而不仅仅是数字索引。所以我们现在枚举每个数字索引和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数组。请记住,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
坏的:(jsHint将抛出错误)
for (var name in item) {
console.log(item[name]);
}
好:
for (var name in item) {
if (item.hasOwnProperty(name)) {
console.log(item[name]);
}
}
当然,这样说有点极端
...永远不要使用for in循环to 枚举数组。从来没有。使用 (var I = 0; 我< arr.length;我+ +)
?
道格拉斯·克罗克福德节选中的这部分值得强调
…第二种形式应该用with 对象……
如果你需要一个关联数组(又名哈希表/字典),其中键是命名的,而不是数字索引,你将不得不实现它作为一个对象,例如var myAssocArray = {key1: "value1", key2: "value2"…};
In this case myAssocArray.length will come up null (because this object doesn't have a 'length' property), and your i < myAssocArray.length won't get you very far. In addition to providing greater convenience, I would expect associative arrays to offer performance advantages in many situations, as the array keys can be useful properties (i.e. an array member's ID property or name), meaning you don't have to iterate through a lengthy array repeatedly evaluating if statements to find the array entry you're after.
无论如何,也感谢JSLint错误消息的解释,我将使用'isOwnProperty'检查现在通过我的无数关联数组交互!
jslint的作者Douglas Crockford就这个问题写过(也说过)很多次。在他的网站的这一页上有一个部分是这样写的:
for Statement A for class of statements should have the following form: for (initialization; condition; update) { statements } for (variable in object) { if (filter) { statements } } The first form should be used with arrays and with loops of a predeterminable number of iterations. The second form should be used with objects. Be aware that members that are added to the prototype of the object will be included in the enumeration. It is wise to program defensively by using the hasOwnProperty method to distinguish the true members of the object: for (variable in object) { if (object.hasOwnProperty(variable)) { statements } }
Crockford还制作了一个关于YUI剧院的系列视频,在视频中他谈到了这一点。如果你对javascript有点兴趣,一定要看Crockford关于javascript的系列视频/演讲。