20
votes

I've been working on JavaScript lately, and everything was fine until I opened my page in IE11. as per Mozilla website .forEach is supported from IE9.

This is the error I got.

SCRIPT438: Object doesn't support property or method 'forEach'

and this is the code.

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!");
        };
    });

I tried polyfill, but to my amusement, Array has a forEach in IE11.

Then where I'm going wrong?

PS: This works fine in Chrome.

4
@Quentin I cannot accept my own answer within 2-days. Or so the error says. - Prajwal
So wait a couple of days. Just don't edit the title of the question to include the word "Solved". - Quentin

4 Answers

35
votes

Finally mystery solved.

Apparently, IE9 and above supports Array.forEach but not for NodeList, which querySelector returns. I tried Array.from() to no avail as it requires ES6 or use ES6-shim.

All I had to do was to convert from nodeList to Array, and I did by this.

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

as appeared in question In Javascript, what is the best way to convert a NodeList to an array

6
votes
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;
 }  
4
votes

To avoid changing the code for every forEach() call, here's a polyfill that worked for me. It's simple and recommended within https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach when running forEach() on a NodeList.

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

I was doing so:

Array.from(document.querySelectorAll(someElements))

The asnwer for me was simply that:

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

Making sure that forEach also exists in Nodelist.