IE从控制台调用时支持forEach(...),但从代码调用时则不支持

时间:2016-12-14 12:40:27

标签: javascript html foreach internet-explorer-11

我在控制台上运行此代码段。在IE中,它按预期产生输出。在Cr和FF中运行相同的参考确认了行为的一致性。

["a", "b"].forEach(function(element) {
  console.log(element);
});

然而,当运行以下脚本时,我收到错误,告诉我该对象没有在其上声明 forEach(...)。问题发生在IE中,但不是在Cr和FF中。

var menus = document.querySelectorAll("ul.application>li>a");
menus.forEach(function(element) { ... }

我已经检查过变量 menus 已经被声明,并且选择它的元素会产生我所期望的,即 menus [0] 存在并且是一个标记。与其他人相比,它在IE中看起来有点不同,但它可能只是不同的再现。

我很幸运能与Cr和FF合作,所以我处理IE的经验有限。谷歌搜索并没有给我太多智慧。

如何进一步排查?

4 个答案:

答案 0 :(得分:6)

基本上document.querySelectorAll会返回一个nodeList数组,就像对象而不是数组一样。在调用数组函数之前,必须将其转换为数组。

var menus = document.querySelectorAll("ul.application>li>a");
menus = [].slice.call(menus);
menus.forEach(function(element) { ... });

如果您的环境支持ES6,则可以使用Array.from()

var menus = document.querySelectorAll("ul.application>li>a");
menus = Array.from(menus);
menus.forEach(function(element) { ... });

答案 1 :(得分:3)

这不是浏览器的问题,更像是使用querySelectorAll获得类似对象的数组。它返回一个NodeList,它是可迭代的,但不是直接使用数组方法。

但你可以从Array.prototype借用这个方法,就像这个

一样
Array.prototype.forEach.call(menu, function(element) { /* ... */ });

如果您想获得第一个真正的数组,可以使用

进行转换
array = Array.apply(null, menu);

答案 2 :(得分:1)

来晚了,但是如果有人遇到相同的问题并且不想/不能用[].forEach.call(elements, fn(el))替换所有的forEach方法,这可能会很有用。这是适用于ie11的polyfill

if (! Object.getOwnPropertyDescriptor(NodeList.prototype, 'forEach')) {
    Object.defineProperty(NodeList.prototype, 'forEach', Object.getOwnPropertyDescriptor(Array.prototype, 'forEach'));
}

答案 3 :(得分:1)

最好的解决方案是在开头添加一行:

window.NodeList && !NodeList.prototype.forEach && (NodeList.prototype.forEach = Array.prototype.forEach) // make IE support forEach

之后,您就可以像在其他普通浏览器中一样在 IE 中使用 forEach。