Search code examples
javascriptfor-loopforeachgetelementsbytagnameselectors-api

forEach works on querySelectorAll, but not getElementsByTagName?


While coding something, I came across something pretty weird.

The following code works just fine:

document.querySelectorAll("button").forEach(function(e) {
    e.addEventListener("click", function() {
        console.log(e);
    });
});

However, the following does not:

document.getElementsByTagName("button").forEach(function(e) {
    e.addEventListener("click", function() {
        console.log(e);
    });
})

I'm very confused here. As far as I can tell, document.getElementsByTagName("button") returns the exact same array as document.querySelectorAll("button"). Am I wrong? What is the problem here? Is it related to forEach?

side notes:

I came across this post but it doesn't answer my question.

just emphasizing: I'm not using jQuery.

P.S. - I am already aware of the differences and pros and cons between forEach vs a regular for loop, so unless forEach is specifically the reason these two functions are not working the same way, the forEach vs for debate is unrelated to my question.


Solution

  • The difference is in whats returned from those methods. querySelectorAll returns a NodeList while getElementsByTagName returns a HTMLCollection. None of them support the generic Array.forEach but NodeList implements its own NodeList.forEach which is what you are hitting here.