我们正在开发一个基于javascript的GIS应用程序,一切都很顺利,直到有人决定启动IE9并在那里进行旋转。你可能已经猜到了,应用程序崩溃了。
原来,由于某些令人费解的原因for..in
循环无法迭代childNodes
:
var xmldoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
xmldoc.loadXML("<i18n><item>one</item><item>two</item></i18n>");
var currentItem = xmldoc.getElementsByTagName("i18n")[0].firstChild;
while (currentItem) {
if (currentItem.nodeType == 1) {
for (var i in currentItem.childNodes) {
console.log(currentItem.childNodes[i]);
}
}
currentItem = currentItem.nextSibling;
}
但是,当上面代码中的内部for
循环替换为
for (var j = 0; j < currentItem.childNodes.length; j++) {
console.log(currentItem.childNodes[j]);
}
一切都按预期工作 - 它可以毫无问题地遍历子节点。
虽然我发现了一种解决方法,但问题仍然令我烦恼,因为不清楚它为何会发生。 XMLDocument和for..in的MSDN文档都没有提及。
这是一个错误还是另一个IE记录不清的奇怪的案例?
答案 0 :(得分:2)
嗯,自DOM spec doesn't define以来不存在应该有数字属性的错误,只有item
去除的[]
方法。
不要使用for..in
。
答案 1 :(得分:2)
简短回答:不要使用for..in
来迭代数组。应始终使用for()
循环迭代数组。只有非数组对象才能使用for...in
。
如果你必须在这里使用for..in
,你应该使用.hasOwnProperty()
来过滤循环,以防止对属于数组原型的属性而不是数组本身进行不必要的迭代
这一点适用于所有 for..in
循环:为了确保您的代码是健壮的,您应该养成使用.hasOwnProperty()
过滤它们的习惯,即使在普通对象上也是如此,但特别是在数组上,因为我们已经知道它们包含其他属性。
See here了解更多关于这一点。