当我能够使用最少量的代码重现错误时,我感到很惊讶。请注意,在此极简主义示例中,未调用Array.indexOf。另请注意,我已经尝试了几种不同的indexOf实现,包括stackoverflow.com中的几种。
该错误是,当在IE中执行for ... in时,会显示三个警报:“indexOf”,“0”和“1”。在FF中,正如人们所预料的那样,只出现两个(“0”,“1”)。
<html>
<body onLoad="test();">
<script language="javascript">
var testArray = ['Foo', 'Bar'];
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function (obj, fromIndex) {
if (fromIndex == null) {
fromIndex = 0;
} else if (fromIndex < 0) {
fromIndex = Math.max(0, this.length + fromIndex);
}
for (var i = fromIndex, j = this.length; i < j; i++) {
if (this[i] === obj)
return i;
}
return -1;
};
}
function test() {
var i;
for(i in testArray) {
alert(i);
}
}
</script>
</body>
</html>
任何人都能解释一下吗?我已经改变了我的代码以使用while
所以我不是在枪口下,但这个真的让我感到难过。它让我想起c。
答案 0 :(得分:4)
请参阅Yahoo!上的“for in Intrigue”用户界面博客。
您的代码在Firefox中按预期工作的原因是因为您尚未在Firefox中添加自己的indexOf
方法。 for in
循环遍历对象原型链中的所有键,包括您添加的indexOf
方法。 Douglas Crockford建议采用以下解决方案:
for (var p in testArray) {
if (testArray.hasOwnProperty(p)) {
alert(testArray[i]);
}
}
或者,您可以过滤掉功能:
for (var p in testArray) {
if (typeof testArray[p] !== "function") {
alert(testArray[i]);
}
}
另外,正如“nickf”指出的那样,最好不要使用for in
循环来迭代数组。 for in
循环用于迭代对象中的键。
史蒂夫
答案 1 :(得分:4)
for .. in
用于循环访问对象属性,绝对不是数组。
坚持标准:
for (var i = 0, l = myArray.length; i < l; ++i) { .. }
Mozilla Developer Centre的更多信息:
for...in
循环不会迭代内置属性。这些包括对象的所有内置方法,例如String的indexOf方法或Object的toString方法。但是,循环将遍历所有用户定义的属性(包括任何覆盖内置属性的属性)。尽管使用它作为迭代数组的方法可能很诱人,但这是一个坏主意。除了数组元素之外,for ... in语句还迭代用户定义的属性,因此如果修改数组的非整数或非正属性(例如,通过向其添加“foo”属性,或者甚至通过添加方法或属性到Array.prototype),for ... in语句将返回除数字索引之外的用户定义属性的名称。