Conceptos básicos de JS: Array#forEach

Array#forEach, o Array.prototype.forEach, es un método que poseen todos lo arrays en JavaScript. Este método nos sirve iterar sobre un array y ejecutar una función por cada elemento del mismo, lo que en palabras más normales significa que vamos a recorrer un array y hacer algo con sus elementos. Veamos un ejemplo:

const numbers = [1, 2, 3];
const doubles = numbers.forEach(number => console.log(number * 2)); // 2 4 6

Lo que hace Array#forEach entonces es llamar la función que pasamos como argumento una vez por cada elemento del array.

Nota: Ya que Array#forEach no devuelve un nuevo array no se pueden agregar otros métodos como Array#map o Array#filter después de un Array#forEach, este debe ser el último método.

Si queremos hacer lo mismo que Array#forEach tendríamos que hacer algo similar a esto:

const numbers = [1, 2, 3];

for (const number of numbers) {
  console.log(number * 2); // 2 4 6
}

Tendríamos que manualmente recorrer el array e ir haciendo console.log de cada valor multiplicado por dos.

Sintaxis

La sintaxis completa de la función es la siguiente

initial.forEach(function callback(currentValue, index, array) {
  // Devuelve un nuevo elemento
}, thisArg);

Array#forEach recibe dos argumentos, una función callback y un valor, cualquiera, que va a ser asignado como this del callback, en caso de usar arrow functions este valor no hace nada. El callback a su vez recibe tres argumentos, la mayoría de las veces se suele usar solo el primero y algunas veces el segundo, el primero es el valor actual por el que estamos pasando en la iteración, el segundo es el índice dentro de nuestro array y el tercero es el mismo array que estamos iterando.

Por último, la función devuelve undefined en vez del array recorrido.

Implementando Array#forEach a mano

Veamos ahora como crear nuestro propio Array#forEach para entender mejor su funcionamiento. Vamos a implementarlo como una función llamada forEach cuyo primer valor va a ser el array a mapear y después vamos a recibir el callback y el valor de this.

function forEach(array, callback, thisArg) {
  const boundCallback = thisArg ? callback.bind(thisArg) : callback;
  for (let index = 0; index < array.length; index++) {
    boundCallback(array[index], index, array);
  }
}

const numbers = [1, 2, 3];
forEach(numbers, number => console.log(number * 2)); //  2 4 6

¿Qué es lo que hicimos? Nuestra función recibe los tres argumentos que dijimos antes, luego crea una constante llamada boundCallback que en caso de que se haya definido thisArg es igual a hacer Function#bind de callback con el valor de thisArg y en caso contrario es igual a callback. Después iteramos el array inicial y al callback, al cual le pasamos el valor actual del array, el índice y el array entero.

Casos de uso

Array#forEach es usado un montón en JavaScript, especialmente cuando se trabaja de una forma funcional. Se puede usar cada vez que se quiera hacer un efecto secundario por cada elemento de un array.

const $inputList = document.querySelectorAll("input");
Array.from($inputList).forEach($select =>
  $select.addEventListener("change", handleChange)
);

Lo que hace el ejemplo es obtener todos los <input> de una página lo que devuelve un objeto NodeList, usando Array.from lo convertimos a un array y usamos Array#forEach empezamos a escuchar el evento change de cada uno usando una función handleChange que podemos definir en nuestro código.

Palabras finales

Este método es muy útil y es usado a diario al trabajar con Arrays en JavaScript. Si no lo habías usado antes te recomiendo probar varios ejemplos de uso para familiarizarte, cuando lo hagas vas a querer usarlo siempre.