SCRIPT438错误在Internet Explorer 11中。

21

最近我一直在学习JavaScript,一切都很顺利,直到在IE11中打开我的页面。根据Mozilla网站的说明,.forEach从IE9开始就被支持。

这是我收到的错误信息:

SCRIPT438:对象不支持“forEach”属性或方法

下面是代码:

var link1 = document.querySelectorAll("nav a");
    var textbox = document.getElementById("OutputWindow");
    link1.forEach(function (element) {
        textbox.innerHTML += "<br/>" + element + "\n";
        element.onclick = function () {
            alert("Hello!");
            console.log("hello!");
            confirm("Hello!");
        };
    });

我尝试使用兼容性代码,但出乎意料的是,在IE11中,Array已经有了forEach方法。

那么我错在哪里了?

PS: 在Chrome中这段代码可以正常工作。


请阅读接受答案是如何工作的? - Quentin
@Quentin 我不能在两天内接受自己的答案。这就是错误提示。 - Prajwal
所以请等几天。只是不要编辑问题的标题,加入“已解决”这个词。 - Quentin
4个回答

36

终于解决了谜团。

显然,IE9及以上版本支持Array.forEach,但不支持NodeList,而querySelector返回的是NodeList。我尝试使用Array.from(),但无济于事,因为它需要ES6或使用ES6-shim

我所要做的就是将nodeList转换为Array,我通过以下方式实现了转换。

Array.prototype.slice.call(document.querySelectorAll("nav a"), 0);

如在问题"In Javascript, what is the best way to convert a NodeList to an array"中出现


其他浏览器都“正常”工作了吗?这不应该是可能的。 - Teemu
嗯……最近似乎有些变化。document.querySelectorAll 曾经返回一个 HTMLCollection(不支持 forEach), 但目前返回一个 NodeList - Teemu
1
@Teemu 是的。它返回“NodeList”,而Chrome支持“NodeList”的“forEach”。 - Prajwal
实际上,按照标准,它不应该这样... 但是根据实践来看,情况就是这样,因此我们从现在开始将采用这种方式。 - Teemu

6
if (typeof Array.prototype.forEach != 'function') {
Array.prototype.forEach = function (callback) {
    for (var i = 0; i < this.length; i++) {
        callback.apply(this, [this[i], i, this]);
    }
 };
}

if (window.NodeList && !NodeList.prototype.forEach) {
    NodeList.prototype.forEach = Array.prototype.forEach;
 }  

1
你能否解释一下你的答案? - Datz
2
感谢您提供这段代码片段,它可能会提供一些有限的、即时的帮助。一个适当的解释将极大地提高其长期价值,因为它可以展示为什么这是一个好的问题解决方案,并使其对未来读者有其他类似问题的人更有用。请[编辑]您的答案以添加一些解释,包括您所做的假设。 - Dwhitz

4
为了避免每次调用forEach()时都要更改代码,这里提供了一个对我有效的 polyfill。在使用NodeList上的forEach()时,它是简单且推荐的方法,可以在 https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach 中查看。
if (window.NodeList && !NodeList.prototype.forEach) {
    NodeList.prototype.forEach = Array.prototype.forEach;
}

1
谢谢,这对我来说是解决方案。我讨厌IE。 - tjans

3
我正在进行以下操作:
Array.from(document.querySelectorAll(someElements))

对我来说,答案很简单:

if (window.NodeList && !NodeList.prototype.forEach) {
   NodeList.prototype.forEach = Array.prototype.forEach;
}

确保forEach也存在于NodeList中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接