it-swarm-es.com

¿Para cada uno sobre una matriz en JavaScript?

¿Cómo puedo recorrer todas las entradas de una matriz usando JavaScript?

Pensé que era algo como esto:

forEach(instance in theArray)

Donde theArray es mi matriz, pero esto parece ser incorrecto.

4335
Dante1986

TL; DR

  • No use for-in a menos que lo use con salvaguardas o al menos sea consciente de por qué podría morderse.
  • Tus mejores apuestas suelen ser

    • un bucle for-ofsolo ES2015 +),
    • Array#forEach ( spec | MDN ) (o sus parientes some y similares) (solo ES5 +),
    • un simple for bucle pasado de moda,
    • o for-in con resguardos.

Pero hay _ (muchasmás para explorar, sigue leyendo ...


JavaScript tiene una poderosa semántica para recorrer en forma de arrays y objetos de tipo array. He dividido la respuesta en dos partes: opciones para arreglos genuinos y opciones para elementos que son solo arreglos -como, como el objeto arguments, otros objetos iterables (ES2015 +), colecciones DOM, y así en.

Notaré rápidamente que puede usar las opciones ES2015 ahora, incluso en los motores ES5, por transpiling ES2015 a ES5. Busque por "ES2015 transpiling"/"ES6 transpiling" para más ...

Bien, echemos un vistazo a nuestras opciones:

Para matrices reales

Tiene tres opciones en ECMAScript 5 ("ES5"), la versión más ampliamente compatible en este momento, y dos más agregadas en ECMAScript 2015 ("ES2015", "ES6"):

  1. Utilice forEach y relacionado (ES5 +)
  2. Use un simple bucle for
  3. Utilice for-incorrectamente
  4. Use for-ofuse un iterador implícitamente) (ES2015 +)
  5. Utilice un iterador explícitamente (ES2015 +)

Detalles:

1. Utilice forEach y relacionado

En cualquier entorno vagamente moderno (por lo tanto, no IE8) donde tiene acceso a las características Array agregadas por ES5 (directamente o usando polyfills), puede usar forEach ( spec | MDN ):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEach acepta una función de devolución de llamada y, opcionalmente, un valor para usar como this cuando se llama a esa devolución de llamada (no se utiliza arriba). Se llama a la devolución de llamada para cada entrada de la matriz, en orden, omitiendo las entradas no existentes en matrices dispersas. Aunque solo usé un argumento arriba, la devolución de llamada se llama con tres: el valor de cada entrada, el índice de esa entrada y una referencia a la matriz sobre la que está iterando (en caso de que su función aún no lo tenga a mano) ).

A menos que esté admitiendo navegadores obsoletos como IE8 (que NetApps muestra con un poco más del 4% de participación de mercado en el momento de escribir este artículo en septiembre de 2016), puede usar forEach en una página web de uso general sin ningún problema. Si es necesario que admita navegadores obsoletos, shimmer/polyfilling forEach se realiza fácilmente (busque "es5 shim" para varias opciones).

forEach tiene la ventaja de que no tiene que declarar las variables de indexación y valor en el ámbito que lo contiene, ya que se suministran como argumentos a la función de iteración y, por lo tanto, están muy bien orientados a esa iteración.

Si está preocupado por el costo de tiempo de ejecución de realizar una llamada de función para cada entrada de matriz, no lo haga; detalles .

Además, forEach es la función de "recorrer todos", pero ES5 definió varias otras funciones útiles de "trabajar a través de la matriz y hacer cosas", que incluyen:

  • every (se detiene en bucle la primera vez que la devolución de llamada devuelve false o algo falsey)
  • some (se detiene en bucle la primera vez que la devolución de llamada devuelve true o algo parecido)
  • filter (crea una nueva matriz que incluye elementos donde la función de filtro devuelve true y omite los que devuelve false)
  • map (crea una nueva matriz a partir de los valores devueltos por la devolución de llamada)
  • reduce (acumula un valor invocando repetidamente la devolución de llamada, pasando los valores anteriores; consulte la especificación para obtener detalles; útil para sumar el contenido de una matriz y muchas otras cosas)
  • reduceRight (como reduce, pero funciona en orden descendente en lugar de ascendente)

2. Usa un simple bucle for

A veces las formas antiguas son las mejores:

var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
    console.log(a[index]);
}

Si la longitud de la matriz no cambiará durante el bucle, y está en un código sensible al rendimiento (poco probable), una versión un poco más complicada que tome la longitud por delante podría ser una _ (pequeñabit Más rápido:

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}

Y/o contando hacia atrás:

var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}

Pero con los modernos motores de JavaScript, es raro que necesites sacar el último trago.

En ES2015 y superior, puede hacer que sus variables de índice y valor sean locales en el bucle for:

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//console.log(index); // Would cause "ReferenceError: index is not defined"
//console.log(value); // Would cause "ReferenceError: value is not defined"

Y cuando haces eso, no solo se recrea value sino también index para cada iteración de bucle, lo que significa que los cierres creados en el cuerpo del bucle mantienen una referencia a la indexy value) creada para esa iteración específica:

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        alert("Index is: " + index);
    });
}

Si tuviera cinco divs, obtendría "El índice es: 0" si hace clic en el primero y el "Índice es: 4" si hace clic en el último. Esto hace _ (notrabajo si usas var en lugar de let.

3. Utilice for-incorrectamente

Obtendrás personas que te dicen que uses for-in, pero eso no es lo que for-in es para . for-in recorre las propiedades enumerables de un objeto, no los índices de una matriz. El orden no está garantizado, ni siquiera en ES2015 (ES6). ES2015 sí define un orden para las propiedades del objeto (a través de [[OwnPropertyKeys]] , [[Enumerate]] , y cosas que las usan como Object.getOwnPropertyKeys ), pero nodefine que for-in seguirá ese orden. (Detalles en esta otra respuesta .)

Aún así, puede ser útil, particularmente para las matrices dispersas , si usa las medidas de seguridad adecuadas:

// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

Tenga en cuenta los dos controles:

  1. Que el objeto tiene su propiedad own por ese nombre (no uno que hereda de su prototipo), y

  2. Que la clave es una cadena numérica de base 10 en su forma de cadena normal y su valor es <= 2 ^ 32 - 2 (que es 4,294,967,294). ¿De dónde viene ese número? Es parte de la definición de un índice de matriz en la especificación . Otros números (no enteros, números negativos, números mayores que 2 ^ 32 - 2) no son índices de matriz. La razón es que 2 ^ 32 - 2es que hace que el mayor valor de índice sea inferior a 2 ^ 32 - 1, que es el valor máximo que puede tener una matriz lengthpor ejemplo, la longitud de una matriz encaja en un entero sin signo de 32 bits.) (Ayuda a RobG por señalar en un comentario en mi blog que mi prueba anterior no estaba del todo bien.)

Eso es un poquito de iteración adicional por repetición de bucle en la mayoría de los arreglos, pero si tiene un arreglo disperso, puede ser una forma más eficiente de realizar un bucle porque solo realiza un bucle para las entradas que realmente existen. Por ejemplo, para la matriz anterior, hacemos un bucle un total de tres veces (para las claves "0", "10", y "10000" - recuerde, son cadenas), no 10,001 veces.

Ahora, no querrá escribir eso cada vez, así que puede poner esto en su caja de herramientas:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}

Y luego lo usaríamos así:

for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}

O si está interesado en una prueba de "lo suficientemente bueno para la mayoría de los casos", puede usar esto, pero mientras está cerca, no es del todo correcto:

for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

4. Utilice for-of (use un iterador implícitamente) (ES2015 +)

ES2015 agrega iteradores a JavaScript. La forma más fácil de usar los iteradores es la nueva declaración for-of. Se parece a esto:

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

Salida:

a B C

Debajo de las cubiertas, se obtiene un iterador de la matriz y se recorre, obteniendo los valores de la misma. Esto no tiene el problema que tiene el uso de for-in, porque usa un iterador definido por el objeto (la matriz), y las matrices definen que sus iteradores se repiten en sus entradas (no en sus propiedades). A diferencia de for-in en ES5, el orden en que se visitan las entradas es el orden numérico de sus índices.

5. Utilice un iterador explícitamente (ES2015 +)

A veces, es posible que desee utilizar un iterador explícitamente. También puedes hacer eso, aunque es mucho más complicado que for-of. Se parece a esto:

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

El iterador es un objeto que coincide con la definición del iterador en la especificación. Su método next devuelve un nuevo objeto de resultado cada vez que lo llama. El objeto de resultado tiene una propiedad, done, que nos dice si está terminada, y una propiedad value con el valor para esa iteración. (done es opcional si sería false, value es opcional si sería undefined.)

El significado de value varía según el iterador; las matrices admiten (al menos) tres funciones que devuelven iteradores:

  • values(): Este es el que he usado anteriormente. Devuelve un iterador donde cada value es la entrada de la matriz para esa iteración ("a", "b", y "c" en el ejemplo anterior).
  • keys(): devuelve un iterador donde cada value es la clave para esa iteración (por lo tanto, para nuestro a anterior, sería "0", luego "1", luego "2").
  • entries(): devuelve un iterador donde cada value es una matriz en la forma [key, value] para esa iteración.

Para objetos similares a matrices

Aparte de los arreglos verdaderos, también hay tipo arreglo objetos que tienen una propiedad length y propiedades con nombres numéricos: NodeList instancias, el arguments objeto, etc. ¿Cómo hacemos un bucle a través de su contenido?

Utilice cualquiera de las opciones anteriores para matrices

Al menos algunos, y posiblemente la mayoría o incluso todos, de los enfoques de matriz anteriores con frecuencia se aplican igualmente a los objetos similares a una matriz:

  1. _ (Use forEach y relacionado (ES5 +)

    Las diversas funciones en Array.prototype son "intencionalmente genéricas" y, por lo general, se pueden usar en objetos similares a matrices a través de Function#call o Function#apply . (Consulte la Advertencia para los objetos provistos por el Host al final de esta respuesta, pero es un problema poco frecuente).

    Supongamos que desea utilizar forEach en una propiedad de NodechildNodes. Tu harias esto

    Array.prototype.forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    

    Si va a hacer eso mucho, es posible que desee tomar una copia de la referencia de la función en una variable para reutilizarla, por ejemplo:

    // (This is all presumably in some scoping function)
    var forEach = Array.prototype.forEach;
    
    // Then later...
    forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    
  2. Use un simple for loop

    Obviamente, un simple for bucle se aplica a objetos similares a matrices.

  3. Utilice for-incorrectamente

    for-in con las mismas salvaguardas que con una matriz también debería funcionar con objetos similares a una matriz; puede aplicarse la advertencia para los objetos provistos por el Anfitrión en el # 1 anterior.

  4. Use for-of (use un iterador implícitamente) (ES2015 +)

    for-of utilizará el iterador proporcionado por el objeto (si lo hay); tendremos que ver cómo se juega con los diversos objetos similares a matrices, particularmente los proporcionados por el Host. Por ejemplo, la especificación para la NodeList de querySelectorAll se actualizó para admitir la iteración. La especificación para la HTMLCollection de getElementsByTagName no fue.

  5. Use un iterador explícitamente (ES2015 +)

    Ver # 4, tendremos que ver cómo juegan los iteradores.

Crea una verdadera matriz

Otras veces, es posible que desee convertir un objeto similar a una matriz en una matriz verdadera. Hacer eso es sorprendentemente fácil:

  1. Utilice el método slice de matrices

    Podemos usar el método de arrays slice, que al igual que los otros métodos mencionados anteriormente es "genéricamente intencionalmente" y, por lo tanto, se puede usar con objetos similares a arreglos, como este:

    var trueArray = Array.prototype.slice.call(arrayLikeObject);
    

    Entonces, por ejemplo, si queremos convertir una NodeList en una verdadera matriz, podríamos hacer esto:

    var divs = Array.prototype.slice.call(document.querySelectorAll("div"));
    

    Consulte la Advertencia para los objetos proporcionados por el Host a continuación. En particular, tenga en cuenta que esto fallará en IE8 y versiones anteriores, lo que no le permite usar objetos provistos por el Host como this de esa manera.

  2. Use la sintaxis spread (...)

    También es posible usar la sintaxis spread de ES2015 con motores de JavaScript que admiten esta función:

    var trueArray = [...iterableObject];
    

    Entonces, por ejemplo, si queremos convertir una NodeList en una verdadera matriz, con una sintaxis extendida esto se vuelve bastante conciso:

    var divs = [...document.querySelectorAll("div")];
    
  3. Utilice Array.from(spec) | (MDN)

    Array.fromES2015 +, pero fácilmente rellenado con polietileno) crea una matriz a partir de un objeto similar a una matriz, y opcionalmente pasa las entradas a través de una función de mapeo primero. Asi que:

    var divs = Array.from(document.querySelectorAll("div"));
    

    O si desea obtener una matriz de los nombres de etiqueta de los elementos con una clase determinada, usará la función de mapeo:

    // Arrow function (ES2015):
    var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);
    
    // Standard function (since `Array.from` can be shimmed):
    var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
        return element.tagName;
    });
    

Advertencia para los objetos proporcionados por el anfitrión

Si usa las funciones Array.prototype con proporcionado por el host objetos similares a una matriz (listas DOM y otras cosas proporcionadas por el navegador en lugar del motor de JavaScript), debe asegurarse de probar en sus entornos de destino para asegurarse El objeto proporcionado por el Host se comporta correctamente. _ (La mayoría se comporta correctamente(ahora), pero es importante realizar una prueba. La razón es que la mayoría de los métodos Array.prototype que probablemente querrá usar se basan en el objeto provisto por el Anfitrión que da una respuesta honesta al resumen [[HasProperty]] operación. A partir de este escrito, los navegadores hacen un muy buen trabajo de esto, pero la especificación 5.1 permitió la posibilidad de que un objeto provisto por el Host no sea honesto. Está en §8.6.2 , varios párrafos debajo de la mesa grande cerca del comienzo de esa sección), donde dice:

Los objetos host pueden implementar estos métodos internos de cualquier manera a menos que se especifique lo contrario; por ejemplo, una posibilidad es que [[Get]] y [[Put]] para un objeto Host en particular, de hecho, busque y almacene valores de propiedad, pero [[HasProperty]] siempre genera false.

(No pude encontrar la verborrea equivalente en la especificación ES2015, pero es probable que siga siendo así.) Una vez más, a partir de este momento se escriben los objetos comunes de tipo matriz proporcionados por el Host en los navegadores modernos [instancias de NodeList, por ejemplo] dohandle [[HasProperty]] correctamente, pero es importante probar).

6345
T.J. Crowder

Editar : Esta respuesta está totalmente desactualizada. Para un enfoque más moderno, mire los métodos disponibles en una matriz . Los métodos de interés pueden ser:

  • para cada
  • mapa
  • filtrar
  • Cremallera
  • reducir
  • cada
  • algunos

La forma estándar de iterar una matriz en JavaScript es un Vanilla for- loop:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

Sin embargo, tenga en cuenta que este enfoque solo es bueno si tiene una matriz densa y cada índice está ocupado por un elemento. Si la matriz es escasa, entonces puede tener problemas de rendimiento con este enfoque, ya que recorrerá una gran cantidad de índices que no existen realmente en la matriz. En este caso, un for .. in- loop podría ser una mejor idea. Sin embargo , debe usar los resguardos apropiados para asegurarse de que solo se actúen las propiedades deseadas de la matriz (es decir, los elementos de la matriz), ya que el for..in- loop también se enumerará en los navegadores heredados, o si las propiedades adicionales se definen como enumerable.

En ECMAScript 5 habrá un método forEach en el prototipo de matriz, pero no es compatible con los navegadores heredados. Por lo tanto, para poder usarlo de manera consistente, debe tener un entorno que lo admita (por ejemplo, Node.js para el servidor de JavaScript), o usar un "Polyfill". El Polyfill para esta funcionalidad es, sin embargo, trivial y ya que hace que el código sea más fácil de leer, es un buen polyfill para incluir.

473
PatrikAkerstrand

Si está utilizando la biblioteca jQuery , puede usar jQuery.each :

$.each(yourArray, function(index, value) {
  // do your stuff here
});

EDITAR:  

Según la pregunta, el usuario desea código en javascript en lugar de jquery, por lo que la edición es

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}
214
Poonam

Bucle hacia atrás

Creo que el reverso para bucle merece una mención aquí:

for (var i = array.length; i--; ) {
     // process array[i]
}

Ventajas:

  • No es necesario declarar una variable len temporal, o compararla con array.length en cada iteración, cualquiera de las cuales puede ser una optimización de un minuto.
  • La eliminación de hermanos del DOM en orden inverso suele ser más eficiente . (El navegador debe hacer menos cambios de elementos en sus matrices internas).
  • Si modifica la matriz mientras hace un bucle, en o después del índice i (por ejemplo, elimina o inserta un elemento en array[i]), entonces un bucle hacia adelante omitirá el elemento que se desplazó hacia la izquierda position i, o vuelva a procesar el ith elemento que se desplazó a la derecha. En un bucle for tradicional, usted podría actualizar i para apuntar al siguiente elemento que necesita procesamiento - 1, pero simplemente invertir la dirección de la iteración suele ser un más simple y solución más elegante .
  • De manera similar, al modificar o eliminar anidado elementos DOM, el procesamiento en reversa puede evitar errores . Por ejemplo, considere modificar el HTML interno de un nodo principal antes de manejar sus hijos. En el momento en que se llegue al nodo secundario, se desconectará del DOM y será reemplazado por un elemento secundario recién creado cuando se escribió el HTML interno del padre.
  • Es más corto para escribir, y leer , que algunas de las otras opciones disponibles. Aunque pierde a forEach() y al for ... of de ES6.

Desventajas:

  • Procesa los elementos en orden inverso. Si estaba creando una nueva matriz a partir de los resultados, o imprimiendo cosas en la pantalla, naturalmente la salida se invertirá con respecto al pedido original.
  • La inserción repetida de hermanos en el DOM como primer hijo para conservar su orden es menos eficiente . (El navegador seguiría teniendo que cambiar las cosas correctamente). Para crear nodos DOM de manera eficiente y ordenada, simplemente haga un bucle hacia delante y agregue como de costumbre (y también use un "fragmento de documento").
  • El bucle inverso es confuso para desarrolladores junior. (Puedes considerar que es una ventaja, dependiendo de tu Outlook).

¿Debo usarlo siempre?

Algunos desarrolladores usan el reverso para el bucle por defecto, a menos que haya una buena razón para hacer un bucle hacia adelante.

Aunque las ganancias de rendimiento son generalmente insignificantes, en cierto modo grita:

"Simplemente haga esto a cada elemento de la lista, ¡no me importa el pedido!"

Sin embargo, en la práctica eso es no en realidad una indicación confiable de intención, ya que es indistinguible de aquellas ocasiones en que ustedhacerse preocupa por el orden, y realmente hacenecesitapara hacer un bucle en reversa. Entonces, de hecho, se necesitaría otra construcción para expresar con precisión la intención de "no importa", algo que actualmente no está disponible en la mayoría de los idiomas, incluido ECMAScript, pero que podría llamarse, por ejemplo, forEachUnordered().

Si el orden no importa, y eficiencia es una preocupación (en el bucle más interno de un juego o motor de animación), puede ser aceptable usar el bucle inverso como su patrón de ir. Solo recuerde que ver un ciclo inverso para en el código existente no significa necesariamente que la orden sea irrelevante.

Es mejor usar forEach ()

En general, para el código de nivel superior donde claridad y seguridad son preocupaciones mayores, recomendaría usar Array::forEach como su patrón predeterminado:

  • Está claro para leer.
  • Indica que i no se cambiará dentro del bloque (lo que siempre es una posible sorpresa que se oculta en los bucles largos for y while).
  • Te da un margen libre para los cierres.
  • Reduce la fuga de variables locales y la colisión accidental con (y la mutación de) las variables externas.

Entonces, cuando vea el reverso del bucle for en su código, es una pista de que se invierte por una buena razón (tal vez una de las razones descritas anteriormente). Y ver un avance tradicional para el bucle puede indicar que el cambio puede tener lugar.

(Si la discusión sobre la intención no tiene sentido para usted, entonces usted y su código pueden beneficiarse al ver la conferencia de Crockford sobre Estilo de programación y su cerebro .)


¿Como funciona?

for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

Notará que i-- es la cláusula central (donde generalmente vemos una comparación) y la última cláusula está vacía (donde generalmente vemos i++). Eso significa que i-- también se usa como condición para la continuación. De manera crucial, se ejecuta y verifica antes en cada iteración.

  • ¿Cómo puede comenzar en array.length sin explotar?

    Debido a que i-- ejecuta antes cada iteración, en la primera iteración estaremos accediendo al elemento en array.length - 1 que evita cualquier problema con Array fuera de los límites undefined artículos.

  • ¿Por qué no deja de iterar antes del índice 0?

    El bucle dejará de iterar cuando la condición i-- se evalúe a un valor falso (cuando se obtiene 0).

    El truco es que, a diferencia de --i, el operador i-- final disminuye i pero produce el valorantesla disminución. Tu consola puede demostrar esto:

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    Así que en la iteración final, i era previamente 1 y la expresión i-- lo cambia a 0 pero en realidad produce 1 (truthy), Y así pasa la condición. En la siguiente iteración, i-- cambia i a -1 pero produce 0 (falsey), lo que hace que la ejecución caiga inmediatamente de la parte inferior del bucle.

    En los forwards de bucle tradicionales, i++ y ++i son intercambiables (como señala Douglas Crockford). Sin embargo, en el reverso para bucle, porque nuestra disminución también es nuestra expresión de condición, debemos mantenernos con i-- si queremos procesar el artículo en el índice 0.


Trivialidades

A algunas personas les gusta dibujar una pequeña flecha en el bucle for inverso, y terminar con un guiño:

for (var i = array.length; i --> 0 ;) {

Los créditos van a WYL para mostrarme los beneficios y los horrores del reverso para el bucle.

94
joeytwiddle

Algunos lenguajes de estilo C - usan foreach para recorrer enumeración. En JavaScript, esto se hace con la estructura de bucle for..in :

var index,
    value;
for (index in obj) {
    value = obj[index];
}

Hay una trampa. for..in recorrerá cada uno de los miembros enumerables del objeto y los miembros en su prototipo. Para evitar leer los valores que se heredan a través del prototipo del objeto, simplemente verifique si la propiedad pertenece al objeto:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

Además, ECMAScript 5 ha agregado un forEach method a Array.prototype que se puede usar para enumerar una matriz usando un calback (el polyfill está en los documentos, por lo que aún puede usarlo para más navegadores):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

Es importante tener en cuenta que Array.prototype.forEach no se interrumpe cuando la devolución de llamada devuelve false. jQuery and Underscore.js proporcionan sus propias variaciones en each para proporcionar bucles que pueden cortocircuitarse.

75
zzzzBov

Si desea realizar un bucle en una matriz, utilice el bucle for de tres partes estándar.

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

Puede obtener algunas optimizaciones de rendimiento almacenando en caché myArray.length o iterando hacia atrás.

34
Quentin

Sé que este es un post antiguo, y ya hay muchas respuestas geniales. Para un poco más de completitud, pensé en lanzar otro usando AngularJS . Por supuesto, esto solo se aplica si está usando Angular, obviamente, sin embargo, me gustaría ponerlo de todos modos.

angular.forEach toma 2 argumentos y un tercer argumento opcional. El primer argumento es el objeto (matriz) para iterar, el segundo argumento es la función del iterador, y el tercer argumento opcional es el contexto del objeto (referido básicamente dentro del bucle como "esto".

Hay diferentes maneras de usar el bucle forEach de angular. El más simple y probablemente el más usado es el

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

Otra forma que es útil para copiar elementos de una matriz a otra es

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.Push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

Sin embargo, no tiene que hacer eso, simplemente puede hacer lo siguiente y es equivalente al ejemplo anterior:

angular.forEach(temp, function(item) {
    temp2.Push(item);
});

Ahora hay ventajas y desventajas de usar la función angular.forEach en lugar del construido en bucle for con sabor a vainilla.

Pros

  • Facilidad de lectura
  • Facilidad de escritura
  • Si está disponible, angular.forEach utilizará el bucle ES5 forEach. Ahora, llegaré a la eficiencia en la sección de contras, ya que los bucles forEach son mucho más lentos que los bucles for. Menciono esto como un profesional porque es bueno ser consistente y estandarizado.

Considere los siguientes 2 bucles anidados, que hacen exactamente lo mismo. Digamos que tenemos 2 matrices de objetos y cada objeto contiene una matriz de resultados, cada uno de los cuales tiene una propiedad Value que es una cadena (o lo que sea). Y digamos que necesitamos iterar sobre cada uno de los resultados y, si son iguales, realice alguna acción: 

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

Por supuesto, este es un ejemplo hipotético muy simple, pero he escrito triple incrustado para bucles utilizando el segundo enfoque y fue muy difícil de leer, y escribir para ese asunto.

Contras

  • Eficiencia. angular.forEach, y el nativo forEach, para el caso, son mucho más lentos que el bucle for normal ... aproximadamente 90% más lento . Así que para grandes conjuntos de datos, es mejor atenerse al bucle nativo for.
  • No hay descanso, continuar, o devolver el soporte. continue realmente es compatible con " accident ", para continuar en angular.forEach simplemente pones una instrucción return; en la función como angular.forEach(array, function(item) { if (someConditionIsTrue) return; }); que hará que continúe fuera de la función para esa iteración. Esto también se debe al hecho de que la variable forEach nativa tampoco admite la interrupción o la continuación.

Estoy seguro de que también hay otros pros y contras, y por favor siéntase libre de agregar lo que considere oportuno. Siento que, en el fondo, si necesita eficiencia, siga con el bucle nativo for para sus necesidades de bucle. Pero, si tus conjuntos de datos son más pequeños y es bueno renunciar a un poco de eficiencia a cambio de la legibilidad y la capacidad de escritura, entonces, por supuesto, agrega un angular.forEach a ese chico malo.

28
user2359695

Si no te importa vaciar la matriz:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

x contendrá el último valor de y y se eliminará de la matriz. También puede usar shift() que dará y eliminará el primer elemento de y.

27
gaby de wilde

A forEach implementación ( ver en jsFiddle ):

function forEach(list,callback) {
  var length = list.length;
  for (var n = 0; n < length; n++) {
    callback.call(list[n]);
  }
}

var myArray = ['hello','world'];

forEach(
  myArray,
  function(){
    alert(this); // do something
  }
);
27
nmoliveira

Una solución fácil ahora sería utilizar la biblioteca underscore.js . Proporciona muchas herramientas útiles, como each, y delegará automáticamente el trabajo a la nativa forEach si está disponible.

Un ejemplo de CodePen de cómo funciona es:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

Ver también

24
Micka

Hay tres implementaciones de foreach en jQuery como sigue.

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3
24
Rajesh Paul

Probablemente el bucle for(i = 0; i < array.length; i++) no sea la mejor opción. ¿Por qué? Si tienes esto:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

El método llamará de array[0] a array[2]. Primero, esto hará referencia primero a las variables que ni siquiera tiene, segundo, no tendría las variables en la matriz, y tercero, esto hará que el código sea más audaz. Mira aquí, es lo que uso:

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

Y si quieres que sea una función, puedes hacer esto:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

Si quieres romper, un poco más de lógica:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

Ejemplo:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

Vuelve:

//Hello
//World
//!!!
22
Federico Piragua

A partir de ES6:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

Donde of evita las rarezas asociadas con in y hace que funcione como el bucle for de cualquier otro idioma, y ​​let se une a i dentro del bucle en lugar de dentro de la función.

Las llaves ({}) se pueden omitir cuando solo hay un comando (por ejemplo, en el ejemplo anterior).

21
Zaz

Este es un iterador para la lista no dispersa donde el índice comienza en 0, que es el escenario típico cuando se trata de document.getElementsByTagName o document.querySelectorAll)

function each( fn, data ) {

    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');

    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   

    return this;
}

Array.prototype.each = each;  

Ejemplos de uso:

Ejemplo 1

var arr = [];
[1, 2, 3].each( function(a){ a.Push( this * this}, arr);
arr = [1, 4, 9]

Ejemplo # 2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

Cada etiqueta p obtiene class="blue"

Ejemplo # 3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

Cada otra etiqueta p obtiene class="red">

Ejemplo # 4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);

Y finalmente, las primeras 20 etiquetas p azules se cambian a verde.

Precaución al utilizar la cadena como función: la función se crea fuera de contexto y debe usarse solo cuando esté seguro del alcance de la variable. De lo contrario, mejor pasar funciones donde el alcance es más intuitivo.

17
Tim

No hay ningún bucle for each en Native JavaScript . Puede usar bibliotecas para obtener esta funcionalidad (recomiendo Underscore.js ), use un simple for in loop.

for (var instance in objects) {
   ...
}

Sin embargo, tenga en cuenta que puede haber razones para usar un bucle for aún más simple (consulte la pregunta sobre el desbordamiento de pila¿Por qué usar "for ... in" con una iteración de matriz es una mala idea?)

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}
17
joidegn

Hay algunas formas para recorrer una matriz en JavaScript, como se muestra a continuación:

para - es el más común. Bloque completo de código para bucles

var languages = ["Java", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

while - loop mientras que una condición es completa. Parece ser el bucle más rápido

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

do/while - también recorre un bloque de código mientras la condición es verdadera, se ejecutará al menos una vez

var text = ""
var i = 0;
do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>

Bucles funcionales - forEach, map, filter, también reduce (recorren la función, pero se usan si necesitas hacer algo con tu matriz, etc.

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

Para obtener más información y ejemplos sobre la programación funcional en arrays, consulte la publicación del blog Programación funcional en JavaScript: mapear, filtrar y reducir.

16
Alireza

ECMAScript5 (la versión en Javascript) para trabajar con Arrays.

forEach - Iteriza a través de cada elemento de la matriz y hace lo que sea necesario con cada elemento.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is the #" + (index+1) + " in musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

En caso de que, más interesado en la operación en la matriz utilizando alguna característica incorporada.

map - Crea una nueva matriz con el resultado de la función de devolución de llamada. Este método es bueno para usar cuando necesite formatear los elementos de su matriz.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

reduce - Como su nombre lo indica, reduce la matriz a un solo valor llamando a la función dada que pasa en el elemento currenct y el resultado de la ejecución anterior.

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

every - Devuelve verdadero o falso si todos los elementos de la matriz pasan la prueba en la función de devolución de llamada.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];  
ages.every(function(elem) {  
  return elem >= 18;
});

// Output: false

filter - Muy similar a todos, excepto que el filtro devuelve una matriz con los elementos que devuelven verdadero a la función dada.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]

Espero que esto sea de utilidad.

14
Anil Kumar Arya

No hay una habilidad incorporada para romper en forEach. Para interrumpir la ejecución, use el Array#some como a continuación:

[1,2,3].some(function(number) {
    return number === 1;
});

Esto funciona porque some devuelve verdadero tan pronto como cualquiera de las devoluciones de llamada, ejecutadas en orden de matriz, devuelve verdadero, cortocircuitando la ejecución del resto. Respuesta original Vea el prototipo de Array para some

14
Priyanshu Chauhan

También me gustaría agregar esto como una composición de un bucle inverso y una respuesta anterior para alguien que también quisiera esta sintaxis.

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

Pros:

El beneficio para esto: Ya tiene la referencia en el primero, así que no será necesario declararlo más adelante con otra línea. Es útil cuando se realiza un bucle a través de la matriz de objetos.

Contras:

Esto se romperá cuando la referencia sea falsa - falsey (indefinido, etc.). Aunque puede ser usado como una ventaja. Sin embargo, sería un poco más difícil de leer. Y también, dependiendo del navegador, puede "no" optimizarse para funcionar más rápido que el original.

11

forma jQuery usando $.map:

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];
10
DanFromGermany

Una forma más cercana a su idea sería utilizar Array.forEach() que acepte una función de clojure que se ejecutará para cada elemento de la matriz.

myArray.forEach(
  (item) => {
    // do something 
    console.log(item);
  }
);

Otra forma viable sería utilizar Array.map() que funciona de la misma manera pero también mutates cada elemento y lo devuelve como:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]
6

Usar bucles con ES6 Desestructurar y Operador de propagación

La destrucción y el uso del operador de propagación han demostrado ser muy útiles para los recién llegados a ES6 por ser más legibles/humanos, aunque algunos veteranos de javascript pueden considerarlo desordenado, los juniors o algunas otras personas pueden encontrarlo útil.

Los siguientes ejemplos usarán for...of statement y .forEach method.

Ejemplos 6, 7 y 8 pueden usarse con cualquier bucle funcional como .map, .filter, .reduce, .sort, .every, .some, para obtener más información sobre estos métodos, consulte el Array Object .

Ejemplo 1: Normal for...of loop - no hay trucos aquí.

let arrSimple = ['a', 'b', 'c'];

for (let letter of arrSimple) {
  console.log(letter);
}

Ejemplo 2: Dividir palabras en caracteres

let arrFruits = ['Apple', 'orange', 'banana'];

for (let [firstLetter, ...restOfTheWord] of arrFruits) {
  // Create a shallow copy using the spread operator
  let [lastLetter] = [...restOfTheWord].reverse();
  console.log(firstLetter, lastLetter, restOfTheWord);

}

Ejemplo 3: Bucle con key y value 

// let arrSimple = ['a', 'b', 'c'];

// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type: 
// `arrWithIndex: [number, string][]`

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);

// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on internet Explorer unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);

for (let [key, value] of arrWithIndex) {
  console.log(key, value);
}

Ejemplo 4: Obtener propiedades de objeto en línea

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];

for (let { name, age: aliasForAge } of arrWithObjects) {
  console.log(name, aliasForAge);
}

Ejemplo 5: Obtenga propiedades de objeto profundas de lo que necesita

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
  console.log(name, firstItemFromTags, restOfTags);
}

Ejemplo 6: Es Ejemplo 3 usado con .forEach

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it

arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
  console.log(forEachIndex, mappedIndex, item);
});

Ejemplo 7: Es Ejemplo 4 usado con .forEach

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];
// NOTE: Destructuring objects while using shorthand functions 
// are required to be surrounded by parenthesis
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
  console.log(name, aliasForAge)
});

Ejemplo 8: Es Ejemplo 5 usado con .forEach

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

arrWithObjectsWithArr.forEach(({
  name,
  tags: [firstItemFromTags, ...restOfTags]
}) => {
  console.log(name, firstItemFromTags, restOfTags);
});

6
darklightcode

La sintaxis lambda no suele funcionar en IE 10 o inferior.

Usualmente uso el

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});


If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters

$("#ul>li").each(function(**index,value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});
5
Murtuza Husain

Puedes llamar a cada uno de esta manera:

let Array = [1,3,2];

theArray.forEach((element)=>{ 
  // use the element of the array
  console.log(element) 
}

el elemento tendrá el valor de cada índice desde 0 hasta la longitud de la matriz.

Salida:

1    
3    
2

Explicacion

forEach está en la clase de prototipo. También puede llamar a esto como theArray.prototype.forEach (...);

prototipo: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

También puede modificar una matriz como esta:

for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}
4
Nouman Dilshad

si desea recorrer la matriz de objetos con la función de flecha:

let arr=[{name:'john',age:50},{name:'clark',age:19},{name:'mohan',age:26}];

arr.forEach((person)=>{
  console.log('i am '+person.name+' and i am '+person.age+ ' old');
})
3
subhashish negi

Resumen:

Cuando se recorre una matriz, a menudo podemos querer lograr uno de los siguientes objetivos:

  1. Queremos iterar sobre la matriz y crear una nueva matriz:

    Array.prototype.map 

  2. Queremos iterar sobre la matriz y no crear una nueva matriz:

    Array.prototype.forEach 

    for..of loop

En JS hay muchas maneras de lograr estos dos objetivos. Sin embargo, algunos son más convenientes que otros. A continuación puede encontrar algunos métodos comúnmente utilizados (la imo más conveniente) para lograr la iteración de matrices en javascript.

Creando una nueva matriz: Map

map() es una función ubicada en Array.prototype que puede transformar cada elemento de una matriz y luego devolver una new array. map() toma como argumento una función de devolución de llamada y funciona de la siguiente manera:

let arr = [1, 2, 3, 4, 5];

let newArr = arr.map((element, index, array) => {
  return element * 2;
})

console.log(arr);
console.log(newArr);

La devolución de llamada que hemos pasado a map() como argumento se ejecuta para cada elemento. Luego se devuelve una matriz que tiene la misma longitud que la matriz original. En este nuevo elemento de matriz se transforma mediante la función de devolución de llamada que se pasa como un argumento a map().

La diferencia distintiva entre map y otro mecanismo de bucle como forEach y un for..of es quemap vuelve como una nueva matriz y deja la matriz antigua intacta (excepto si la manipulas explícitamente con ideas como splice). 

También tenga en cuenta que la devolución de llamada de la función map proporciona como segundo argumento el número de índice de la iteración actual. Además, el tercer argumento proporciona la matriz en la que se llamó map. A veces estas propiedades pueden ser muy útiles.

Bucle usando forEach

forEach es una función que se encuentra en Array.prototype que toma una función de devolución de llamada como un argumento. A continuación, ejecuta esta función de devolución de llamada para cada elemento de la matriz. A diferencia de la función map(), la función forEach no devuelve nada (undefined). Por ejemplo:

let arr = [1, 2, 3, 4, 5];

arr.forEach((element, index, array) => {

  console.log(element * 2);

  if (index === 4) {
    console.log(array)
  }
  // index, and oldArray are provided as 2nd and 3th argument by the callback

})

console.log(arr);

Al igual que la función map, la devolución de llamada forEach proporciona como segundo argumento el número de índice de la iteración actual. También el tercer argumento proporciona la matriz en la que se llamó forEach

Recorrer los elementos usando for..of

El bucle for..of recorre cada elemento de una matriz (o cualquier otro objeto iterable). Funciona de la siguiente manera:

let arr = [1, 2, 3, 4, 5];

for(let element of arr) {
  console.log(element * 2);
}

En el ejemplo anterior, element representa un elemento de matriz y arr es la matriz que queremos hacer un bucle. No es que el nombre element sea arbitrario y podríamos haber elegido cualquier otro nombre como 'el' o algo más declarativo cuando sea aplicable. 

No confunda el bucle for..in con el bucle for..of. for..in recorrerá todas las propiedades enumerables de la matriz, mientras que el for..of solo recorrerá los elementos de la matriz. Por ejemplo:

let arr = [1, 2, 3, 4, 5];

arr.foo = 'foo';

for(let element of arr) {
  console.log(element);
}

for(let element in arr) {
  console.log(element);
}

2

Si tiene una matriz masiva, debe usar iterators para ganar algo de eficiencia. Los iteradores son propiedad de ciertas colecciones de JavaScript (como Map , Set , String , Array ). Incluso, for..of usesiteratorunder-the-hood.

Los iteradores mejoran la eficiencia al permitirle consumir los elementos en una lista de uno en uno como si fueran un flujo. Lo que hace especial a un iterador es cómo atraviesa una colección. Otros bucles deben cargar toda la colección por adelantado para iterar sobre ella, mientras que un iterador solo necesita conocer la posición actual en la colección. 

Accede al elemento actual llamando al método next del iterador. El siguiente método devolverá lavaluedel elemento actual y unabooleanpara indicar cuándo ha llegado al final de la colección. El siguiente es un ejemplo de cómo crear un iterador a partir de una matriz. 

Transforme su matriz regular a iterador usando el método values() de esta manera: 

    const myArr = [2,3,4]

let it = myArr.values();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

También puede transformar su matriz regular a iterador usando Symbol.iterator como esto: 

const myArr = [2,3,4]

let it = myArr[Symbol.iterator]();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

También puede transformar su array regular en una iterator como esto: 

let myArr = [8, 10, 12];

function makeIterator(array) {
    var nextIndex = 0;
    
    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
};

var it = makeIterator(myArr);

console.log(it.next().value);   // {value: 8, done: false}
console.log(it.next().value);   // {value: 10, done: false}
console.log(it.next().value);   // {value: 12, done: false}
console.log(it.next().value);   // {value: undefined, done: true}

NOTA

  • Los iteradores son de naturaleza agotable. 
  • Los objetos no son iterable por defecto. Use for..in en ese caso porque en lugar de valores funciona con claves.

Puede leer más sobre iteration protocolaquí

1
BlackBeard
var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})
1
John

// Looping through arrays using foreach  ES6 way

var data = new Array(1,2,3,4,5);
data.forEach((val,index) => {
    console.log("index :",index); // index
	console.log("value :", val); // value
});

0
arul prince

Puede usar la API forEach () (proporcionada por Javascript) que acepta una función como devolución de llamada y se ejecuta una vez para cada elemento presente dentro de la matriz.

https://fullstackgeek.blogspot.com/2019/01/arrays-in-javascript-part-2.html

0
Ayush Jain

Vengo de python y encontré esta forma mucho más clara.
theArray es la matriz, siendo la instancia el elemento de la matriz

for(let instance of theArray)
{
    console.log("The instance",instance);
}

o

for( instance in theArray)
{
  console.log("The instance",instance);
}

comparar con:

theArray.forEach(function(instance) {
    console.log(instance);
});

pero al final del día ambos están haciendo lo mismo.

0
Peko Chan

Si desea mantener su código de manera funcional, use map:

theArray.map(instance => do_something);

De esta manera, generará una nueva matriz para operaciones futuras y omitirá cualquier efecto secundario no deseable.

0
alejoko

Si quieres usar forEach(), se verá así: 

theArray.forEach ( element => {
    console.log(element);
});

Si quieres usar for(), se verá así: 

for(let idx = 0; idx < theArray.length; idx++){
    let element = theArray[idx];
    console.log(element);
}
0
Harunur Rashid