Pojawiło się parę pomysłów na obsługę tablic i DOM, ale myślę, że warto byłoby nieco uporządkować dwie kwestie, tak dla przyszłych czytelników początkujących w HTML i JS.
Po pierwsze błędem jest nadawanie tego samego ID dla kilku elementów. Nie wynika to tak na prawdę z tzw. dobrych praktyk, lecz z faktu, do czego służy element ID. Otóż przeglądarki indeksują wewnętrznie elementy po ID, dlatego jedną z najszybszych metod dostępu do DOM jest właśnie metoda getElementById, gdyż odnosi się ona do elementów zaindeksowanych. Nadając wielokrotnie to samo ID zaburzamy sens indeksacji.
I druga kwestia, a mianowicie zastosowanie metody forEach na obiekcie zwróconym przez metodę querySelectorAll. Jest to oczywiście poprawne, jednakże należy zdawać sobie sprawę jakie faktycznie obiekty zwracają metody związane z obsługą DOM.
var a = document.getElementsByTagName('p'),
b = document.querySelectorAll('p'),
c = [1,2,3]; //zwykła tablica
typeof a; //'object'
typeof b; //'object'
typeof c; //'object'
typeof a.forEach; //'undefined' metoda nie istnieje!
typeof b.forEach; //'function' oki, metoda istnieje
typeof c.forEach; //'function'
//ale a i b to nie "zwykłe" tablice:
typeof a.filter; //'undefined'
typeof b.filter; //'undfined'
typeof c.filter; //'function'
Object.getPrototypeOf(a).toString(); //'[object HTMLCollection]'
Object.getPrototypeOf(b).toString(); //'[object NodeList]'
Object.getPrototypeOf(c).toString(); //''
Object.prototype.toString.call(c); //'[object Array]'
Jak widać tylko zmienna c jest "zwykłą" tablicą JavaScript ze wszystkimi metodami "tablicowymi". Zmienna b, której wartość "stworzyła" metoda querySelectorAll posiada metodę forEach dziedziczoną prototypowo po NodeList, ale nie posiada wielu innych metod tablicowych jak map, sort, filter, reduce itp. Zmienna a z kolei posiada właściwości dziedziczone prototypowo po HTMLCollection, lecz obiekt ten nie posiada już metody forEach.
Z tych względów należy świadomie dobierać metody pobierające referencje do DOM w zależności nie tylko od rodzaju selektora, ale również od tego co chcemy z tymi elementami dalej robić. Rozwiązaniem uniwersalnym jest przekształcenie zwracanego obiektu w "typową" tablicę, który odziedziczy metody po Array.prototype:
//Metoda stosowana dawniej:
var a = Array.prototype.slice.call(document.querySelectorAll('p'));
//Metoda ES6:
var b = [...document.querySelectorAll('p')];
typeof a.filter; //'function'
typeof b.filter; //'function'
Od tej chwili tablice a i b zawierają referencje do elementów DOM, ale dziedziczą prototypowo po Array.prototype wszystkie metody "tablicowe" i nie musimy się już martwić i zastanawiać dlaczego raz forEach (i inne metody) działa dobrze, a za chwilę wyrzuca błąd...