Andrew Andrew - 1 month ago 12
Javascript Question

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.

Answer

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.