For-each sobre una matriz en JavaScript?


¿Cómo puedo recorrer todas las entradas de un array usando JavaScript?

Pensé que era algo como esto:

forEach(instance in theArray)

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

Author: T.J. Crowder, 2012-02-17

28 answers

TL; DR

  • No uses for-in a menos que lo uses con salvaguardas o al menos seas consciente de por qué podría morderte.
  • Sus mejores apuestas suelen ser

    • a for-of bucle (solo ES2015+),
    • Array#forEach (spec | MDN) (o sus parientes some y tales) (ES5+ solamente),
    • un simple bucle anticuado for,
    • o for-in con salvaguardia.

Pero hay mucho más para explorar, sigue leyendo...


JavaScript tiene una poderosa semántica para bucear a través de matrices y objetos similares a matrices. He dividido la respuesta en dos partes: Opciones para arrays genuinos, y opciones para cosas que son solo array-como, como el objeto arguments, otros objetos iterables (ES2015+), colecciones DOM, y así sucesivamente.

Rápidamente notaré que puedes usar el ES2015 options now, even on ES5 engines, by transpiling ES2015 to ES5. Buscar "ES2015 transpiling" /" ES6 transpiling"para más...

Bien, veamos nuestras opciones: {[142]]}

Para Matrices Reales

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

  1. Use forEach y relacionados (ES5+)
  2. Use un bucle for simple
  3. Uso for-in correctamente
  4. Use for-of (use un iterador implícitamente) (ES2015+)
  5. Use un iterador explícitamente (ES2015+)

Detalles:

1. Use forEach y relacionados

En cualquier entorno vagamente moderno (por lo tanto, no IE8) donde tenga acceso a las características Array agregadas por ES5 (directamente o utilizando 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 al llamar a esa devolución de llamada (no utilizada anteriormente). La devolución de llamada se llama para cada entrada en la matriz, en orden, omitiendo entradas inexistentes en matrices dispersas. Aunque solo usé un argumento anterior, 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 no tenga ya es práctico).

A menos que esté soportando navegadores obsoletos como IE8 (que NetApps muestra en poco más del 4% de cuota de mercado a partir de este escrito en septiembre de 2016), puede usar felizmente forEach en una página web de propósito general sin una cuña. Si necesita admitir navegadores obsoletos, shimming / polyfilling forEach se hace fácilmente (busque "es5 shim" para varias opciones).

forEach tiene la ventaja de que no tiene que declarar variables de indexación y valor en el ámbito que contiene, como se suministran como argumentos a la función de iteración, y tan bien delimitado a sólo esa iteración.

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

Además, forEach es la función" loop through them all", pero ES5 definió varias otras funciones útiles para "trabajar su camino a través de la matriz y hacer cosas", incluyendo:

  • every (deja de hacer loop la primera vez la devolución de llamada devuelve false o algo así falsey)
  • some (deja de hacer loop la primera vez que la devolución de llamada devuelve true o algo verdadero)
  • filter (crea un nuevo array que incluye elementos donde la función filter devuelve true y omite los que devuelve false)
  • map (crea un nuevo array a partir de los valores devueltos por la devolución de llamada)
  • reduce (construye un valor por repetidamente llamando a la devolución de llamada, pasando valores anteriores; vea la especificación para los detalles; útil para sumar el contenido de un array y muchas otras cosas)
  • reduceRight (como reduce, pero funciona en orden descendente en lugar de ascendente)

2. Utilice un bucle for simple

A veces las viejas costumbres son las mejores: {[142]]}

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 cambia durante el bucle, y está en código sensible al rendimiento (poco probable), un poco más versión complicada agarrar la longitud por delante podría ser un tiny un poco 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 motores JavaScript modernos, es raro que necesite sacar ese último poco de jugo.

En ES2015 y versiones posteriores, puede hacer que sus variables de índice y valor sean locales para 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 value sino también index se recrea para cada iteración de bucle, lo que significa los cierres creados en el cuerpo del bucle mantienen una referencia a index (y value) creados 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 tuvieras cinco divs, obtendrías "Index is: 0" si hicieras clic en el primero y "Index is: 4" si hicieras clic en el último. Esto hace no trabajar si se utiliza var en lugar de let.

3. Uso for-in correctamente

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

Aún así, puede ser útil, particularmente para disperso arrays , si utiliza las salvaguardas apropiadas:

// `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 las dos comprobaciones:

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

  2. Que la clave es una cadena numérica base - 10 en su forma de cadena normal y su valor es en el pliego de condiciones. Otros números (no enteros, números negativos, números mayores que 2^32-2) no son índices de matriz. La razón es 2^32 - 2 es que eso hace que el mayor valor del índice sea menor que 2^32 - 1, que es el valor máximo que puede tener un array length. (Por ejemplo, la longitud de una matriz encaja en un entero sin signo de 32 bits.) (Accesorios para RobG por señalar en un comentario en mi entrada de blog que mi prueba anterior no fue del todo derecho.)

Eso es un poco de sobrecarga añadida por iteración de bucle en la mayoría de los arrays, pero si tiene un array disperso, puede ser una forma más eficiente de bucle porque solo loops para entradas que realmente existen. Por ejemplo, para la matriz anterior, loop un total de tres veces (para claves "0", "10", y "10000" - recuerde, son cadenas), no 10.001 veces.

Ahora, usted no querrá escribir eso cada vez, por lo que podría poner esto en su instrumental:

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í: {[142]]}

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

O si está interesado en una prueba "lo suficientemente buena para la mayoría de los casos", podría usar esto, pero aunque 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. Use for-of (use un iterador implícitamente) (ES2015+)

ES2015 agrega iteradores a JavaScript. La forma más fácil de usar iteradores es la nueva instrucción for-of. Parece que esto:

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

Salida:

a
b
c

Debajo de las cubiertas, que obtiene un iterador de la matriz y loops a través de ella, obteniendo los valores de ella. Esto no tiene el problema que tiene usar for-in, porque usa un iterador definido por el objeto (el array), y los arrays definen que sus iteradores iteran a través de sus entradas (no sus propiedades). A diferencia de for-in en ES5, el orden en el que se visitan las entradas es el orden numérico de su índices.

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

A Veces, es posible que desee utilizar un iterador explícitamente. Usted puede hacer eso también, aunque es mucho clunkier que for-of. Se ve así:

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 nextdevuelve un nuevo objeto resultado cada vez que lo llamas. El objeto result tiene una propiedad, done, que nos dice si está hecho, y un property 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 dependiendo del iterador; los arrays admiten (al menos) tres funciones que devuelven iteradores:

  • values(): Este es el que usé arriba. Devuelve un iterador donde cada value es la entrada de 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 (así que para nuestro a anterior, eso sería "0", luego "1", luego "2").
  • entries(): Devuelve un iterador donde cada value es un array en la forma [key, value] para esa iteración.

Para Objetos Tipo Array

Aparte de los arrays verdaderos, también hay objetos similares a un array que tienen una propiedad length y propiedades con nombres numéricos: instancias NodeList, el objeto arguments, etc. ¿Cómo lo hacemos ¿recorrer 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 bien a objetos similares a una matriz:

  1. Use forEach y afines (ES5+)

    Las diversas funciones en Array.prototype son "intencionalmente genéricas" y generalmente se pueden usar en objetos similares a matrices a través de Function#call o Function#apply. (Ver el Advertencia para los objetos proporcionados por el host al final de esta respuesta, pero es un problema raro.)

    Supongamos que desea usar forEach en una propiedad Node's childNodes. Usted haría esto:

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

    Si vas a hacer eso mucho, es posible que desee tomar una copia de la referencia de la función en una variable para su reutilización, 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. Utilice un bucle for

    Obviamente, un bucle simple for se aplica a una matriz objeto.

  3. Uso for-in correctamente

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

  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 tipo array, en particular los proporcionados por el anfitrión. Por ejemplo, la especificación para el NodeList de querySelectorAll se actualizó para admitir la iteración. La especificación para el HTMLCollection de getElementsByTagName no.

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

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

Crear una matriz verdadera

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 slice método de matrices

    Podemos usar el método slice de matrices, que al igual que los otros métodos mencionados anteriormente es "intencionalmente genérico" y por lo tanto se puede usar con objetos similares a matrices, como esto:{[142]]}

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

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

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

    Vea la advertencia para los objetos proporcionados por el host a continuación. In particular, note que esto fallará en IE8 y anteriores, que no le permiten usar objetos proporcionados por el host como this así.

  2. Use sintaxis de propagación (...)

    También es posible usar la sintaxis spread de ES2015 con motores JavaScript que admiten esta característica:

    var trueArray = [...iterableObject];
    

    Así que, por ejemplo, si queremos convertir un NodeList en una matriz verdadera, con sintaxis de propagación esto se vuelve bastante sucinto:

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

    Array.from (ES2015+, pero fácilmente polyfilled) crea una matriz a partir de un objeto similar a una matriz, pasando opcionalmente las entradas a través de una función de asignación primero. So:

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

    O si desea obtener una matriz de los nombres de las etiquetas de los elementos con una clase dada, utilizaría la función de asignación:

    // 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 el host proporcionado objetos

Si utiliza Array.prototype funciones con objetos de matriz proporcionados por el host (listas DOM y otras cosas proporcionadas por el navegador en lugar del motor JavaScript), debe asegurarse de realizar pruebas en sus entornos de destino para asegurarse de que el objeto proporcionado por el host se comporta correctamente. La mayoría se comportan correctamente (ahora), pero es importante probar. La razón es que la mayoría de los métodos Array.prototype que es probable que desee utilizar se basan en el objeto proporcionado por el host que da un respuesta honesta a lo abstracto [[HasProperty]] operación. En el momento de escribir esto, los navegadores hacen un muy buen trabajo de esto, pero la especificación 5.1 permitió la posibilidad de que un objeto proporcionado por el host no sea honesto. Está dentro.§8.6.2, varios párrafos debajo de la gran tabla 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 obtiene y almacena valores de propiedad, pero [[HasProperty]] siempre genera false.

(No pude encontrar la verborrea equivalente en la especificación ES2015, pero está obligado a seguir siendo el caso.) Una vez más, al escribir esto, los objetos comunes de tipo array proporcionados por el host en los navegadores modernos [NodeList instancias, por ejemplo] hacen manejar [[HasProperty]] correctamente, pero es importante probar.)

 6107
Author: T.J. Crowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-16 13:23:53

Editar : Esta respuesta está irremediablemente desactualizada. Para un enfoque más moderno, vea los métodos disponibles en un array. Los métodos de interés podrían ser:

  • forEach
  • mapa
  • filtro
  • zip
  • reducir
  • cada
  • algunos

La forma estándar de iterar una matriz en JavaScript es un bucle vainilla for:

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

Tenga en cuenta, sin embargo, que este enfoque solo es bueno si tiene un matriz densa, y cada índice está ocupado por un elemento. Si el array es escaso, entonces puede encontrarse con problemas de rendimiento con este enfoque, ya que iterará sobre muchos índices que no realmente existen en el array. En este caso, un bucle for .. in podría ser una mejor idea. Sin embargo , debe usar las salvaguardas apropiadas para asegurarse de que solo se actúen sobre las propiedades deseadas del array (es decir, los elementos del array), ya que el for..in-loop también se enumerará en navegadores heredados, o si las propiedades adicionales están definidas 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 consistentemente, debe tener un entorno que lo soporte (por ejemplo, Node.js para JavaScript del lado del servidor), o use 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 una buena polyfill a incluir.

 455
Author: PatrikAkerstrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-06 06:11:45

Si usted está utilizando el jQuery biblioteca, puede utilizar jQuery.cada uno:

$.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].
}
 207
Author: Poonam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-12 05:17:40

Bucle hacia atrás

Creo que el reverse for loop merece una mención aquí:

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

Ventajas:

  • No es necesario declarar una variable temporal len, o comparar con array.length en cada iteración, cualquiera de las cuales podría ser una optimización de minutos.
  • Eliminar los hermanos del DOM en orden inverso suele ser más eficiente. (El navegador necesita hacer menos desplazamiento de elementos en su interno matriz.)
  • Si modifica el array mientras hace un bucle, en o después de index i (por ejemplo, elimina o inserta un elemento en array[i]), entonces un bucle hacia adelante saltaría el elemento que se desplazó a la izquierda a la posición i, o volver a procesar el iésimo elemento que se desplazó a la derecha. En un bucle for tradicional, podría actualizar i para apuntar al siguiente elemento que necesita procesamiento-1, pero simplemente invertir la dirección de la iteración a menudo es un más simple y solución más elegante.
  • Del mismo modo, al modificar o eliminar elementos DOM anidados, el procesamiento en reversa puede eludir errores. Por ejemplo, considere modificar el innerHTML de un nodo padre antes de manejar sus hijos. En el momento en que se alcance el nodo hijo, se separará del DOM, habiendo sido reemplazado por un hijo recién creado cuando se escribió el innerHTML del padre.
  • Es más corto para escribir, y leer, que algunas de las otras opciones disponibles. Aunque pierde ante forEach() y ante for ... of de ES6.

Desventajas:

  • Procesa los elementos en orden inverso. Si estuviera construyendo una nueva matriz a partir de los resultados, o imprimiendo cosas en pantalla, naturalmente la salida se invertirá con respecto al orden original.
  • Insertar repetidamente hermanos en el DOM como primer hijo para conservar su orden es menos eficiente. (El navegador seguiría teniendo que cambiar las cosas a la derecha.) Para crear nodos DOM de manera eficiente y en orden, simplemente haga un bucle hacia adelante y anexe como normal (y también use un "fragmento de documento").
  • El bucle inverso es confuso para los desarrolladores junior. (Usted puede considerar que una ventaja, dependiendo de su perspectiva.)

¿Debería usarlo siempre?

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

Aunque las ganancias de rendimiento son generalmente insignificantes, grita: {[36]]}

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

Sin embargo, en la práctica eso no es en realidad una indicación confiable de intención, ya que es indistinguible de aquellas ocasiones en las que do se preocupan por el orden, y realmente lo hacen necesidad para hacer un bucle en reversa. Así que de hecho se necesitaría otra construcción para expresar con precisión la intención "don't care", algo que actualmente no está disponible en la mayoría de los idiomas, incluyendo ECMAScript, pero que podría llamarse, por ejemplo, forEachUnordered().

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

Es mejor usar forEach ()

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

  • Es claro de leer.
  • Indica que i no va a ser desplazado dentro del bloque (lo que siempre es una posible sorpresa escondida en largos bucles for y while.)
  • da tienes un margen libre para cierres.
  • Reduce la fuga de variables locales y la colisión accidental con (y la mutación de) variables externas.

Luego, cuando ves el bucle for inverso en tu código, es una pista de que se invierte por una buena razón (quizás una de las razones descritas anteriormente). Y ver un bucle forward for tradicional puede indicar que el cambio puede tener lugar.

(Si la discusión de la intención no tiene sentido para usted, entonces usted y su código pueden benefíciese de ver la conferencia de Crockford sobre El Estilo de programación y Su Cerebro .)


¿Cómo funciona?

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

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

Notará que i-- es la cláusula del medio (donde usualmente vemos una comparación) y la última cláusula está vacía (donde usualmente vemos i++). Eso significa que i-- también se usa como la condición para la continuación. Crucialmente, se ejecuta y comprueba antes de cada iteración.

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

    Debido a que i-- se ejecuta antes de cada iteración, en la primera iteración realmente accederemos al elemento en {[17] } lo que evita cualquier problema con Array-fuera de 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 falsey (cuando arroje 0).

    El truco es que a diferencia de --i, el operador final i-- decrementa i pero produce el valor antes el decremento. Su consola puede demostrar esto:

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

    [5, 5, 4]

    Así que en la iteración final, i fue previamente 1 y la expresión i-- la cambia a 0 pero en realidad rinde 1 (truthy), y así la condición pasa. En la siguiente iteración i-- cambios i a -1 pero los rendimientos 0 (falsey), causando que la ejecución se caiga inmediatamente de la parte inferior del bucle.

    En los delanteros tradicionales para bucle, i++ y ++i son intercambiables (como señala Douglas Crockford). Sin embargo, en el bucle for inverso, debido a que nuestro decremento es también nuestra expresión de condición, debemos seguir con i-- si queremos procesar el elemento en el índice 0.


Trivia

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

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

Los créditos van a WYL por mostrarme los beneficios y horrores del bucle for inverso.

 88
Author: joeytwiddle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:09

Algunos lenguajes de estilo C usan foreach para recorrer enumeraciones. En JavaScript esto se hace con el for..in estructura del bucle :

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 de su prototipo. Para evitar leer 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 añadido un forEach método para Array.prototype que se puede usar para enumerar sobre una matriz usando un calback (el polyfill está en los documentos, por lo que aún puede usarlo para navegadores más antiguos):

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

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

 72
Author: zzzzBov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-13 01:18:21

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

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.

 31
Author: Quentin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-17 13:55:46

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
  }
);
 25
Author: nmoliveira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-18 12:22:55

Si no te importa vaciar el array:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

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

 25
Author: gaby de wilde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-30 18:37:32

Sé que este es un post antiguo, y ya hay muchas grandes respuestas. Para un poco más de completitud, pensé en agregar otro usando AngularJS . Por supuesto, esto solo se aplica si estás 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 sobre, el segundo argumento es la función iterador, y el tercer argumento opcional es el objeto contexto (básicamente referido dentro del bucle como 'esto'.

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

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 tienes que hacer eso, simplemente puedes hacer lo siguiente y es equivalente al ejemplo anterior:

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

Ahora hay pros y contras de usar la función angular.forEach en lugar de la función construida en bucle con sabor a vainilla for.

Pros

  • Fácil legibilidad
  • Fácil escritura
  • Si está disponible, angular.forEach utilizará el bucle ES5 forEach. Ahora, voy a llegar a efficientcy en la sección cons, 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 tener 2 matrices de objetos y cada objeto contiene una matriz de resultados, cada uno de los cuales tiene una propiedad de valor que es una cadena (o lo que sea). Y digamos que necesitamos iterar sobre cada uno de los resultados y si son iguales entonces realizar 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
        }
    }
}

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

Cons

  • Eficiencia. angular.forEach, y el nativo forEach, para el caso, ambos son mucho más lentos que el bucle normal for....aproximadamente 90% más lento. Así que para grandes conjuntos de datos, lo mejor es atenerse al bucle nativo for.
  • No hay soporte para romper, continuar o devolver. continue es realmente soportado por " accidente ", para continuar en un angular.forEach simplemente ponga una instrucción return; en la función como angular.forEach(array, function(item) { if (someConditionIsTrue) return; }); que hará que continuar fuera de la función para esa iteración. Esto también se debe al hecho de que el nativo forEach no soporta break ni continue.

Estoy seguro de que hay varios otros pros y contras, así, y por favor no dude en añadir cualquiera que considere conveniente. Siento que, en pocas palabras, si necesita eficiencia, quédese con solo el bucle nativo for para sus necesidades de bucle. Pero, si sus conjuntos de datos son más pequeños y una cierta eficiencia está bien para renunciar a cambio de legibilidad y escritura, entonces por todos los medios tira un angular.forEach en ese chico malo.

 25
Author: user2359695,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-20 22:56:52

Una solución fácil ahora sería usar el subrayado .js library . Proporciona muchas herramientas útiles, como each y delegará automáticamente el trabajo al forEach nativo si está disponible.

Un ejemplo de CodePen de cómo funciona es:

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

Véase también

 24
Author: Micka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-30 22:23:09

Probablemente el bucle for(i = 0; i < array.length; i++) no es la mejor opción. ¿Por qué? Si usted tiene 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 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 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+"!!");
    }
});

Devuelve:

//Hello
//World
//!!!
 21
Author: Federico Piragua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-08 10:49:27

Hay tres implementaciones de foreach en jQuery de la siguiente manera.

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
 21
Author: Rajesh Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-08 10:50:06

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 lenguaje, 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).

 19
Author: Zaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-20 15:21:43

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

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 de desbordamiento de pilaPor qué está usando "for...in" con la iteración de matriz es una mala idea?)

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}
 15
Author: joidegn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:36

Este es un iterador para lista NO dispersa donde el índice comienza en 0, que es el escenario típico cuando se trata de documento.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 el las primeras 20 etiquetas p azules se cambian a verde

Precaución al usar string 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, es mejor pasar funciones donde el alcance es más intuitivo.

 15
Author: Tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-29 12:28:20

Hay algunas formas de recorrer un array en JavaScript, como se muestra a continuación:

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

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 - bucle mientras una condición está a través. 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, ejecutará al menos una tiempo

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 (hacen un bucle a través de 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 matrices, consulte la entrada del blogProgramación funcional en JavaScript: mapear, filtrar y reducir.

 14
Author: Alireza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-27 12:29:50

No hay capacidad incorporada para entrar 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 true tan pronto como cualquiera de las devoluciones de llamada, ejecutadas en orden de matriz, devuelve true, cortocircuitando la ejecución del resto. Respuesta original ver Prototipo de matriz para algunos

 12
Author: Priyanshu Chauhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:59

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

ForEach - Itera a través de cada elemento en la matriz y hacer 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 el caso , 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 callback. Este método es bueno para ser utilizado cuando necesita 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 el nombre dice que reduce la matriz a un solo valor llamando a la función dada pasando 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 true o false si todos los elementos del array pasan la prueba en la función callback.

// 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 filter devuelve una matriz con los elementos que devuelven true 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 útil.

 12
Author: Anil Kumar Arya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-30 17:36:57

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);
}

Ventajas:

El beneficio para esto: Usted tiene la referencia ya en la primera como que no tendrá que ser declarado más tarde con otra línea. Es útil cuando se realiza un bucle a través de la matriz de objetos.

Contras:

Esto se romperá siempre que la referencia sea false - falsey (undefined, etc.). Se puede utilizar como un ventaja sin embargo. Sin embargo, lo haría un poco más difícil de leer. Y también dependiendo del navegador puede ser "no" optimizado para trabajar más rápido que el original.

 9
Author: Volkan Seçkin Akbayır,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-19 16:27:44

JQuery way 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];
 8
Author: DanFromGermany,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-01 11:15:26

Una forma más cercana a su idea sería usar Array.forEach() que acepta una función clojure que se ejecutará para cada elemento del array.

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

Otra forma viable sería usar 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]
 4
Author: Ante Jablan Adamović,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-09 15:31:44

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

Normalmente 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);
});
 3
Author: Murtuza Husain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-16 08:09:53
var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})
 1
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-15 22:48:33

Puedes llamar a forEach así:

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 del array.

Salida:

1    
3    
2

Explicación:

ForEach está en clase prototipo. también puede llamar a esto como theArray.prototipo.forEach (...);

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

También puede alterar sobre una matriz como esta:

for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}
 1
Author: Nouman Dilshad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-17 12:30:51

Si quieres usar forEach(), se verá como -

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

Si quieres usar for(), se verá como -

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

 0
Author: Harunur Rashid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-30 09:05:30

Si tiene una matriz masiva, debe usar iterators para ganar algo de eficiencia. Los iteradores son una propiedad de ciertos JavaScript colecciones (como Map, Set, String, Array). Incluso, for..of utiliza iterator bajo el capó.

Los iteradores mejoran la eficiencia al permitirle consumir los elementos de una lista uno a la vez como si fueran una secuencia. Lo que hace especial a un iterador es cómo atraviesa colección. Otros bucles necesitan 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.

Se accede al elemento actual llamando al método next del iterador. El siguiente método devolverá el value del tema actual y un boolean para indicar cuándo ha llegado al final de la recogida. El siguiente es un ejemplo de creación de un iterador a partir de una matriz.

Transforme su matriz regular a iterador usando values() método como este:

    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 así:

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 a un iterator así:

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. Uso for..in en ese caso porque en lugar de valores funciona con claves.

Puedes leer más sobre iteration protocol aquí .

 0
Author: BlackBeard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-06 11:32:03

Resumen:

Al iterar sobre un array a menudo podemos querer lograr uno de los siguientes objetivos:

  1. Queremos iterar sobre el array y crear un nuevo array:

    Array.prototype.map

  2. Queremos iterar sobre el array y no crear un nuevo array:

    Array.prototype.forEach

    for..of bucle

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

Creando un nuevo array: Map

map() es una función ubicada en Array.prototype que puede transformar cada elemento de una matriz y luego devuelve una nueva matriz. 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 un el argumento se ejecuta para cada elemento. Luego se devuelve un array que tiene la misma longitud que el array original. En este nuevo array el elemento es transformado por la función callback pasada como argumento a map().

La diferencia distintiva entre map y otro mecanismo de bucle como forEach y un bucle for..of es que map devuelve como nuevo array y deja intacto el array antiguo (excepto si explicity lo manipula con thinks like splice).

También tenga en cuenta que la devolución de llamada de la función map proporciona como segundo argumento el número í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 argumento. Luego ejecuta esta función de devolución de llamada para cada elemento de la matriz. En contraste con la función map() el forEach la función 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 índice de la iteración actual. También el tercer argumento proporciona la matriz en la que se llamó forEach.

Bucle a través de elementos usando for..of

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

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

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

En el ejemplo anterior element significa un elemento array y arr es el array que queremos repetir. No es que el nombre element sea arbitrario y podríamos haber elegido cualquier otro nombre como 'el' o algo más declarativo cuando esto es aplicable.

No confundas el bucle for..in con el bucle for..of. for..in recorrerá todas las propiedades enumerables de la matriz, mientras que el bucle for..of solo recorrerá los elementos de la matriz. Para 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);
}
 0
Author: Willem van der Veen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-08 10:11:23

function printList(callback) {
    // do your printList work
    console.log('printList is done');
    callback();
}

function updateDB(callback) {
    // do your updateDB work
    console.log('updateDB is done');
    callback()
}

function getDistanceWithLatLong(callback) {
    // do your getDistanceWithLatLong work
    console.log('getDistanceWithLatLong is done');
    callback();
}

function runSearchInOrder(callback) {
    getDistanceWithLatLong(function() {
        updateDB(function() {
            printList(callback);
        });
    });
}

runSearchInOrder(function(){console.log('finished')});

Output salida getDistanceWithLatLong is done updateDB está hecho printList se hace terminado

 -2
Author: Avinash Maurya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-01 10:18:28