¿Cómo puedo recorrer todas las entradas de una matriz usando JavaScript?
Pensé que era algo como esto:
forEach(instance in theArray)
¿Dónde theArray
está mi matriz, pero esto parece ser incorrecto?
TL; DR
for-in
menos que lo use con medidas de seguridad o al menos sepa por qué podría morderlo.Tus mejores apuestas son usualmente
Pero hay mucho más por explorar, sigue leyendo ...
JavaScript tiene una semántica poderosa para recorrer las matrices y los objetos de tipo matriz. He dividido la respuesta en dos partes: opciones para matrices genuinas y opciones para cosas que son simplemente como matrices, como el arguments
objeto, otros objetos iterables (ES2015 +), colecciones DOM, etc.
Notaré rápidamente que puede usar las opciones de ES2015 ahora , incluso en motores ES5, al trasladar ES2015 a ES5. Busque "Transpiling ES2015" / "Transpiling ES6" para más ...
Bien, veamos nuestras opciones:
Tiene tres opciones en ECMAScript 5 ("ES5"), la versión más ampliamente admitida en este momento y dos más agregadas en ECMAScript 2015 ("ES2015", "ES6"):
forEach
y relacionados (ES5 +)for
bucle simplefor-in
correctamentefor-of
(usar un iterador implícitamente) (ES2015 +)Detalles:
forEach
y relacionadosEn cualquier entorno vagamente moderno (por lo tanto, no IE8) donde tiene acceso a las Array
funciones 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 utilizada anteriormente). Se llama a la devolución de llamada para cada entrada en la matriz, en orden, omitiendo las entradas inexistentes en matrices dispersas. Aunque solo utilicé 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 lo tenga a mano) )
A menos que sea compatible con navegadores obsoletos como IE8 (que NetApps muestra con una participación de mercado de poco más del 4% a partir de este escrito en septiembre de 2016), puede usarlo felizmente forEach
en una página web de uso general sin una cuña. Si necesita admitir navegadores obsoletos, el shimming / polyfilling forEach
se realiza fácilmente (busque "es5 shim" para ver varias opciones).
forEach
tiene el beneficio de que no tiene que declarar las variables de indexación y valor en el ámbito que lo contiene, ya que se proporcionan como argumentos para la función de iteración, y se enfocan tan bien en esa iteración.
Si le preocupa el costo de tiempo de ejecución de realizar una llamada de función para cada entrada de matriz, no se preocupe; detalles .
Además, forEach
es la función de "recorrer a través de todos", pero ES5 definió varias otras funciones útiles de "trabajar a través de la matriz y hacer cosas", que incluyen:
every
(deja de repetirse la primera vez que vuelve la devolución de llamada false
o algo falsey)some
(deja de repetirse la primera vez que vuelve la devolución de llamada true
o algo verdadero)filter
(crea una nueva matriz que incluye elementos donde regresa la función de filtro true
y omite los que regresa false
)map
(crea una nueva matriz a partir de los valores devueltos por la devolución de llamada)reduce
(construye un valor llamando repetidamente a la devolución de llamada, pasando 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)for
bucle simpleA veces las viejas formas 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 es en el código sensibles al rendimiento (poco probable), una versión ligeramente más complicado agarrar la longitud en la delantera podría ser un pequeño 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 necesites sacar ese último jugo.
En ES2015 y superior, puede hacer que sus variables de índice y valor sean locales en el for
ciclo:
let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
let value = a[index];
console.log(index, value);
}
//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 que también index
se recrea para cada iteración del bucle, lo que significa que los cierres creados en el cuerpo del bucle mantienen una referencia al index
(y value
) creado para esa iteración específica:
let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
divs[index].addEventListener('click', e => {
console.log("Index is: " + index);
});
}
Si tuviera cinco divs, obtendría "Índice es: 0" si hizo clic en el primero e "Índice es: 4" si hizo clic en el último. Esto no funciona si lo usa en var
lugar de let
.
for-in
correctamenteObtendrá personas que le dicen que use for-in
, pero eso no for-in
es para lo que sirve . for-in
recorre las propiedades enumerables de un objeto , no los índices de una matriz. El pedido no está garantizado , ni siquiera en ES2015 (ES6). ES2015 + define un orden para las propiedades de los objetos (vía [[OwnPropertyKeys]]
, [[Enumerate]]
y las cosas que los usan como Object.getOwnPropertyKeys
), pero no definió que for-in
seguiría ese orden; ES2020 lo hizo, sin embargo. (Detalles en esta otra respuesta ).
Los únicos casos de uso reales para for-in
una matriz son:
Mirando solo ese primer ejemplo: puede usar for-in
para visitar esos elementos de matriz dispersos si usa 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 checks are
/^0$|^[1-9]\d*$/.test(key) && // explained
key <= 4294967294 // below
) {
console.log(a[key]);
}
}
Tenga en cuenta los tres controles:
Que el objeto tiene su propia propiedad con ese nombre (no uno que herede de su prototipo), y
Que la clave son todos los dígitos decimales (p. Ej., Forma de cadena normal, no notación científica), y
Que el valor de la clave cuando se coacciona a un número 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 por la que 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 length
puede tener una matriz . (Por ejemplo, la longitud de una matriz cabe en un entero sin signo de 32 bits). (Apoya a RobG por señalar en un comentario en mi publicación de blog que mi prueba anterior no era del todo correcta).
No harías eso en código en línea, por supuesto. Escribirías una función de utilidad. Quizás:
for-of
(use un iterador implícitamente) (ES2015 +)ES2015 agregó iteradores a JavaScript. La forma más fácil de usar iteradores es la nueva for-of
declaración. Se parece a esto:
const a = ["a", "b", "c"];
for (const val of a) {
console.log(val);
}
Debajo de las cubiertas, eso obtiene un iterador del conjunto y lo recorre, obteniendo los valores de él. Esto no tiene el problema que for-in
tiene usar , porque usa un iterador definido por el objeto (la matriz), y las matrices definen que sus iteradores iteran a través de sus entradas (no sus propiedades). A diferencia for-in
de ES5, el orden en que se visitan las entradas es el orden numérico de sus índices.
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:
const a = ["a", "b", "c"];
const it = a.values();
let entry;
while (!(entry = it.next()).done) {
console.log(entry.value);
}
El iterador es un objeto que coincide con la definición de iterador en la especificación. Su next
método devuelve un nuevo objeto de resultado cada vez que lo llama. El objeto resultante tiene una propiedad done
que nos dice si está hecho y una propiedad value
con el valor para esa iteración. ( done
es opcional si lo fuera false
, value
es opcional si lo fuera 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 usé arriba. Se devuelve un iterador que 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 uno value
es la clave para esa iteración (por lo que para nuestro a
anterior, sería "0"
, entonces "1"
, entonces "2"
).entries()
: Devuelve un iterador donde cada uno value
es una matriz en el formulario [key, value]
para esa iteración.Además de las matrices verdaderas, también hay objetos en forma de matriz que tienen una length
propiedad y propiedades con nombres numéricos: NodeList
instancias, el arguments
objeto, etc. ¿Cómo recorremos sus contenidos?
Al menos algunos, y posiblemente la mayoría o incluso todos, los enfoques de matriz anteriores se aplican con frecuencia igualmente bien a objetos similares a una matriz:
Uso forEach
y relacionados (ES5 +)
Las diversas funciones en Array.prototype
son "intencionalmente genéricas" y, por lo general, se pueden usar en objetos tipo matriz a través de Function#call
o Function#apply
. (Consulte la Advertencia para los objetos proporcionados por el host al final de esta respuesta, pero es un problema poco frecuente).
Suponga que desea utilizar forEach
en una Node
's childNodes
propiedad. Harías esto:
Array.prototype.forEach.call(node.childNodes, function(child) {
// Do something with `child`
});
Si va a hacer eso mucho, es posible que desee obtener una copia de la referencia de 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`
});
Usa un for
bucle simple
Obviamente, un for
bucle simple se aplica a objetos tipo matriz.
Usar for-in
correctamente
for-in
con las mismas garantías que con una matriz, también debería funcionar con objetos similares a una matriz; se puede aplicar la advertencia para los objetos proporcionados por el host en el n. ° 1 anterior.
Usar for-of
(usar un iterador implícitamente) (ES2015 +)
for-of
usa el iterador proporcionado por el objeto (si lo hay). Eso incluye objetos proporcionados por el host. Por ejemplo, la especificación para NodeList
from querySelectorAll
se actualizó para admitir la iteración. La especificación para el HTMLCollection
de getElementsByTagName
no era.
Use un iterador explícitamente (ES2015 +)
Ver # 4.
Otras veces, es posible que desee convertir un objeto tipo matriz en una matriz verdadera. Hacer eso es sorprendentemente fácil:
Usa el slice
método de matrices
Podemos usar el slice
método de matrices, que al igual que los otros métodos mencionados anteriormente es "intencionalmente genérico" y, por lo tanto, puede usarse con objetos similares a una matriz, como este:
var trueArray = Array.prototype.slice.call(arrayLikeObject);
Entonces, por ejemplo, si queremos convertir a NodeList
en una verdadera matriz, 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. En particular, tenga en cuenta que esto fallará en IE8 y versiones anteriores, lo que no le permite usar objetos proporcionados por el host de this
esa manera.
Usar sintaxis de propagación ( ...
)
También es posible usar la sintaxis extendida de ES2015 con motores JavaScript que admiten esta función. Como for-of
, esto usa el iterador proporcionado por el objeto (ver # 4 en la sección anterior):
var trueArray = [...iterableObject];
Entonces, por ejemplo, si queremos convertir una NodeList
matriz verdadera, con sintaxis extendida esto se vuelve bastante sucinto:
var divs = [...document.querySelectorAll("div")];
Utilizar Array.from
Array.from
(especificación) | (MDN) (ES2015 +, pero fácilmente rellenado) crea una matriz a partir de un objeto similar a una matriz, opcionalmente pasando primero las entradas a través de una función de mapeo. Entonces:
var divs = Array.from(document.querySelectorAll("div"));
O si desea obtener una matriz de nombres de etiquetas de los elementos con una clase determinada, usaría 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;
});
Si usa Array.prototype
funciones con objetos de tipo matriz proporcionados por el host (listas DOM y otras cosas proporcionadas por el navegador en lugar del motor de 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 comporta correctamente (ahora), pero es importante realizar una prueba. La razón es que la mayoría de los Array.prototype
métodos que es probable que desee utilizar se basan en el objeto proporcionado por el host que da una respuesta honesta a la [[HasProperty]]
operación abstracta . Al escribir estas líneas, 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á en §8.6.2 , varios párrafos debajo de la gran mesa 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 particular, de hecho, obtenga y almacene valores de propiedad, pero[[HasProperty]]
siempre genera falso .
(No pude encontrar la verborrea equivalente en la especificación ES2015, pero está obligado a seguir siendo el caso.) Una vez más, a partir de este escrito el host proporcionado por el arreglo de objetos similares en los navegadores modernos [común NodeList
de los casos, por ejemplo] hacer mango [[HasProperty]]
correctamente, pero es importante hacer la prueba).
.forEach
no se puede romper de manera eficiente. Tienes que lanzar una excepción para realizar el descanso.
some
. (Hubiera preferido permitir el descanso forEach
también, pero, um, no me preguntaron. ;-))
,
después k=0
, no un ;
. Recuerde, la programación es muchas cosas, una de las cuales es prestar mucha atención a los detalles ... :-)
length
no es un método). :-)
Nota : Esta respuesta está irremediablemente desactualizada. Para un enfoque más moderno, mire los métodos disponibles en una matriz . Los métodos de interés pueden ser:
La forma estándar de iterar una matriz en JavaScript es un for
bucle de vainilla :
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 encontrar problemas de rendimiento con este enfoque, ya que iterará sobre muchos índices que realmente no existen en la matriz. En este caso, un for .. in
bucle podría ser una mejor idea. Sin embargo , debe usar las salvaguardas apropiadas para garantizar que solo se actúen las propiedades deseadas de la matriz (es decir, los elementos de la matriz), ya que el for..in
bucle 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 JavaScript del lado del servidor) o usar un "Polyfill". Sin embargo, el Polyfill para esta funcionalidad es trivial y, dado que hace que el código sea más fácil de leer, es un buen polyfill para incluir.
for(instance in objArray)
no es un uso correcto? me parece más simple, pero escucho que hablas de que no es una forma correcta de uso.
var
palabra clave. Si hubiéramos usado un punto y coma, entonces element
habría sido declarado en el ámbito global (o, más bien, JSHint nos habría gritado antes de que llegara a producción).
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].
}
Creo que el reverso de loop merece una mención aquí:
for (var i = array.length; i--; ) {
// process array[i]
}
len
variable temporal ni comparar array.length
en cada iteración, ya que cualquiera de las dos podría ser una optimización por minuto.array[i]
), entonces un bucle hacia adelante omitirá el elemento que se desplazó a la izquierda a la posición i , o volverá a procesar el ítem i . desplazado a la derecha. En un bucle for tradicional, puede actualizar i para señalar el siguiente elemento que necesita procesamiento - 1, pero simplemente invertir la dirección de la iteración suele ser una solución más simple y elegante .forEach()
y para ES6 for ... of
.Algunos desarrolladores usan el bucle inverso para de forma predeterminada , a menos que haya una buena razón para avanzar.
Aunque las ganancias de rendimiento generalmente son insignificantes, grita:
"Simplemente haga esto a cada elemento de la lista, ¡no me importa el pedido!"
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 te importa el orden y realmente necesitas hacer un ciclo en reversa. Entonces, de hecho, se necesitaría otra construcción para expresar con precisión la intención de "no me 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 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 inverso para su patrón de inicio. Solo recuerde que ver un bucle inverso para en el código existente no significa necesariamente que el orden sea irrelevante.
En general, para el código de nivel superior donde la claridad y la seguridad son mayores preocupaciones, anteriormente recomendé usarlo Array::forEach
como patrón predeterminado para el bucle (aunque en estos días prefiero usarlo for..of
). Las razones para preferir forEach
sobre un bucle inverso son:
for
y while
bucles).Luego, cuando vea el bucle inverso para 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 bucle de avance for tradicional puede indicar que puede tener lugar un cambio.
(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 ).
Existe un debate sobre si es preferible for..of
o forEach()
no:
Para obtener la máxima compatibilidad con el navegador, se for..of
requiere un polyfill para los iteradores, lo que hace que su aplicación sea un poco más lenta de ejecutar y un poco más grande de descarga.
Por esa razón (y para alentar el uso de map
y filter
), ¡ algunas guías de estilo front-end se prohíben por for..of
completo!
Pero las preocupaciones anteriores no son aplicables a las aplicaciones de Node.js, donde for..of
ahora está bien soportado.
Y además await
no funciona por dentro forEach()
. Usar for..of
es el patrón más claro en este caso.
Personalmente, tiendo a usar lo que parece más fácil de leer, a menos que el rendimiento o la minificación se hayan convertido en una preocupación importante. Así que en estos días yo prefiero usar for..of
en lugar de forEach()
, pero voy a utilizar siempre map
o filter
o find
o some
cuando sea aplicable. (Por el bien de mis colegas, rara vez uso reduce
).
for (var i = 0; i < array.length; i++) { ... } // Forwards
for (var i = array.length; i--; ) { ... } // Reverse
Notarás 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. Crucialmente, se ejecuta y se verifica antes de cada iteración.
¿Cómo puede comenzar array.length
sin explotar?
Debido a que se i--
ejecuta antes de cada iteración, en la primera iteración realmente tendremos acceso al elemento en el array.length - 1
que evita cualquier problema con los elementos fuera de los límites de la matriz undefined
.
¿Por qué no deja de iterar antes del índice 0?
El ciclo dejará de iterar cuando la condición se i--
evalúe como un valor falsey (cuando produce 0).
El truco es que --i
, a diferencia , el i--
operador final disminuye i
pero produce el valor antes de la disminución. Su consola puede demostrar esto:
> var i = 5; [i, i--, i];
[5, 5, 4]
Así que en la iteración final, i estaba anteriormente 1 y la i--
expresión cambia a 0 , pero en realidad el rendimiento de 1 (Truthy), y así la condición pasa. En la siguiente iteración i--
cambia de i a -1 pero produce 0 (falsey), lo que hace que la ejecución se salga inmediatamente del fondo del bucle.
En el tradicional for for loop, i++
y ++i
son intercambiables (como señala Douglas Crockford). Sin embargo, en el reverso del bucle for, dado que nuestro decremento también es nuestra expresión de condición, debemos seguir i--
si queremos procesar el elemento en el índice 0.
A algunas personas les gusta dibujar una pequeña flecha en el for
bucle inverso y terminar con un guiño:
for (var i = array.length; i --> 0 ;) {
Los créditos van a WYL por mostrarme los beneficios y los horrores del bucle inverso.
Algunos lenguajes de estilo C se utilizan foreach
para recorrer las enumeraciones. En JavaScript, esto se hace con la for..in
estructura de 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 agregado un forEach
método 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 vuelve la devolución de llamada false
. jQuery y Underscore.js proporcionan sus propias variaciones each
para proporcionar bucles que se pueden cortocircuitar.
each
métodos que permiten return false
ser utilizados para salir del ciclo, pero con forEach
esto no es una opción. Se podría usar un indicador externo (es decir if (flag) return;
, pero solo evitaría que el resto del cuerpo de la función se ejecute, forEach
seguiría iterando en toda la colección.
Si desea realizar un bucle sobre una matriz, use el for
bucle estándar de tres partes .
for (var i = 0; i < myArray.length; i++) {
var arrayItem = myArray[i];
}
Puede obtener algunas optimizaciones de rendimiento al almacenar en caché myArray.length
o iterar al revés.
length
. ;)
,
después de una tarea no introduce un nuevo global, por lo que su sugerencia está bien . Estaba confundiendo esto por un problema diferente: usar =
después de una asignación crea un nuevo global.
var i, length, arrayItem;
antes del bucle para evitar este malentendido.
Sé que esta es una publicación antigua, y ya hay muchas respuestas geniales. Para un poco más de integridad, pensé que lanzaría 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 iteradora, y el tercer argumento opcional es el contexto del objeto (básicamente denominado dentro del bucle como 'esto'.
Hay diferentes formas 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 ú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 el angular.forEach
función en lugar del for
bucle incorporado con sabor a vainilla .
Pros
angular.forEach
usará el ES5 para cada bucle. Ahora, llegaré a la eficiencia en la sección 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, entonces 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
}
}
}
De acuerdo, 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.
Contras
angular.forEach
, y los nativos forEach
, para el caso, son mucho más lentos que el for
ciclo normal ... aproximadamente un 90% más lento . Por lo tanto, para conjuntos de datos grandes, es mejor atenerse al for
ciclo nativo .continue
en realidad está respaldado por " accidente ", para continuar en un angular.forEach
simple poner una return;
declaración 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 el nativoforEach
no admite interrupción o continuación tampoco.Estoy seguro de que también hay otros pros y contras, y siéntase libre de agregar cualquiera que considere conveniente. Creo que, en resumen, si necesita eficiencia, quédese solo con el for
bucle nativo para sus necesidades de bucle. Pero, si sus conjuntos de datos son más pequeños y se puede renunciar a una cierta eficiencia a cambio de legibilidad y capacidad de escritura, entonces de todos modos arroje angular.forEach
a ese chico malo.
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()
cual le dará y quitará el primer elemento y
.
[1, 2, undefined, 3]
.
[1, 2, 0, 3]
o[true, true, false, true]
Una implementación forEach ( 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
}
);
Probablemente el for(i = 0; i < array.length; i++)
bucle 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 primero hará referencia a 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
//!!!
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
A partir de ECMAScript 6:
list = [0, 1, 2, 3]
for (let obj of list) {
console.log(obj)
}
Donde of
evita las rarezas asociadas in
y hace que funcione como el for
bucle de cualquier otro lenguaje, y se let
une 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).
Una solución fácil ahora sería usar la biblioteca underscore.js . Proporciona muchas herramientas útiles, como each
y delegará automáticamente el trabajo al nativo forEach
si está disponible.
Un ejemplo de CodePen de cómo funciona es:
var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});
Array.prototype.forEach()
.for each (variable in object)
está en desuso como parte del estándar ECMA-357 ( EAX ).for (variable of object)
como parte de la propuesta de Harmony (ECMAScript 6).No hay ningún for each
bucle en JavaScript nativo . Puede usar bibliotecas para obtener esta funcionalidad (recomiendo Underscore.js ), use un for
bucle simple .
for (var instance in objects) {
...
}
Sin embargo, tenga en cuenta que puede haber razones para usar un for
bucle aún más simple (consulte la pregunta de desbordamiento de pila ¿ Por qué usar "for ... in" con iteración de matriz es una mala idea? )
var instance;
for (var i=0; i < objects.length; i++) {
var instance = objects[i];
...
}
Este es un iterador para una 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'
);
Cualquier 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 usar una cadena como función: la función se crea fuera de contexto y debe usarse solo cuando esté seguro del alcance variable. De lo contrario, es mejor pasar funciones donde el alcance es más intuitivo.
Hay algunas formas de recorrer una matriz 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 se cumple una condición. Parece ser el ciclo 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
(que bucle a través de la función, pero se utilizan si hay que hacer algo con su 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 programación funcional en matrices, consulte la publicación de blog Programación funcional en JavaScript: mapear, filtrar y reducir .
forEach
no es un bucle "funcional" ya que no devuelve uno nuevo Array
(en realidad no devuelve nada), solo itera.
ECMAScript 5 (la versión en JavaScript) para trabajar con matrices:
forEach : repite 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 #" + (index+1) + " in the 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 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 usarse 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']
reducir : como su nombre lo indica, reduce la matriz a un solo valor llamando a la función dada que pasa en el elemento actual 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
cada - 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
filtro : 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]
No hay capacidad incorporada para entrar forEach
. Para interrumpir la ejecución, use lo Array#some
siguiente:
[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
ver prototipo de matriz para algunos
También me gustaría agregar esto como una composición de un bucle inverso y una respuesta anterior para alguien a quien también le gustaría 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í no será necesario declararla más adelante con otra línea. Es útil al recorrer en bucle la matriz de objetos.
Contras:
Esto se romperá siempre que la referencia sea falsa: falsey (indefinida, etc.). Sin embargo, se puede usar como una ventaja. Sin embargo, sería un poco más difícil de leer. Y también, dependiendo del navegador, puede "no" estar optimizado para funcionar más rápido que el original.
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];
[undefined, 2, undefined, 4, undefined, 6, undefined]
.
Uso de bucles con la desestructuración de ECMAScript 6 y el operador de propagación
La desestructuración y el uso del operador de propagación han demostrado ser bastante útiles para los recién llegados a ECMAScript 6 por ser más legibles / estéticos, aunque algunos veteranos de JavaScript podrían considerarlo desordenado. Juniors o algunas otras personas pueden encontrarlo útil.
Los siguientes ejemplos utilizarán la
for...of
declaración y el.forEach
método.Ejemplos 6, 7 y 8 se pueden utilizar con cualquier bucles funcionales como
.map
,.filter
,.reduce
,.sort
,.every
,.some
. Para obtener más información sobre estos métodos, consulte el objeto Array .
Ejemplo 1:for...of
bucle normal : 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 una key
yvalue
// 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 las propiedades del 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 objetos profundos 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: ¿Se usa el ejemplo 3 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: ¿Se usa el ejemplo 4 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 parentheses
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
console.log(name, aliasForAge)
});
Ejemplo 8: ¿ Se usa el ejemplo 5 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);
});
Una forma más cercana a su idea sería usar una Array.forEach()
que acepte una función de cierre que se ejecutará para cada elemento de la matriz.
myArray.forEach(
(item) => {
// Do something
console.log(item);
}
);
Otra forma viable sería usar el Array.map()
que funciona de la misma manera, pero también toma todos los valores que devuelve y los devuelve en una nueva matriz (esencialmente asignando cada elemento a uno nuevo), de esta manera:
var myArray = [1, 2, 3];
myArray = myArray.map(
(item) => {
return item + 1;
}
);
console.log(myArray); // [2, 3, 4]
map
no muta los elementos de la matriz, porque devuelve una nueva matriz, siendo los elementos de esa nueva el resultado de aplicar la función a los elementos de la matriz anterior.
Puedes llamar a cada uno de estos:
forEach
iterará sobre la matriz que proporcione y para cada iteración tendrá element
el valor de esa iteración. Si necesita un índice, puede obtener el índice actual pasando i
el segundo parámetro en la función de devolución de llamada para forEach.
Foreach es básicamente una función de orden superior, que toma otra función como parámetro.
let theArray= [1,3,2];
theArray.forEach((element) => {
// Use the element of the array
console.log(element)
}
Salida:
1
3
2
También puede iterar sobre una matriz como esta:
for (let i=0; i<theArray.length; i++) {
console.log(i); // i will have the value of each index
}
Si desea recorrer un conjunto 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');
})
La sintaxis lambda no suele funcionar en Internet Explorer 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);
});
Si eres un fanático de jQuery y ya tienes un archivo jQuery en ejecución, debes invertir las posiciones de los parámetros de índice y valor
$("#ul>li").each(function(**index, value**){
console.log("value of the looped element" + value);
console.log("index of the looped element" + index);
});
Si tiene una matriz masiva que debe usar iterators
para ganar algo de eficiencia. Los iteradores son una propiedad de ciertas colecciones de JavaScript (como Map
, Set
, String
, Array
). Incluso, for..of
utiliza iterator
debajo del capó.
Los iteradores mejoran la eficiencia al permitirle consumir los elementos en una lista uno a la vez como si fueran una secuencia. Lo que hace que un iterador sea especial es cómo atraviesa una 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.
Accede al elemento actual llamando al next
método del iterador . El siguiente método devolverá el value
del elemento actual y una boolean
para indicar cuándo ha llegado al final de la colección. El siguiente es un ejemplo de creación de un iterador a partir de una matriz.
Transforme su matriz regular en iterador usando un 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 en 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 puedes transformar tu regular array
en algo 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 :
iterable
por defecto. Úselo for..in
en ese caso porque en lugar de valores funciona con claves.Puedes leer más sobre iteration protocol
aquí .
Si quieres usarlo forEach()
, se verá así:
theArray.forEach ( element => {
console.log(element);
});
Si quieres usarlo for()
, se verá así:
for(let idx = 0; idx < theArray.length; idx++){
let element = theArray[idx];
console.log(element);
}
Según la nueva característica actualizada ECMAScript 6 (ES6) y ECMAScript 2015, puede usar las siguientes opciones con bucles:
para bucles
for(var i = 0; i < 5; i++){
console.log(i);
}
// Output: 0,1,2,3,4
para ... en bucles
let obj = {"a":1, "b":2}
for(let k in obj){
console.log(k)
}
// Output: a,b
Array.forEach ()
let array = [1,2,3,4]
array.forEach((x) => {
console.log(x);
})
// Output: 1,2,3,4
para ... de bucles
let array = [1,2,3,4]
for(let x of array){
console.log(x);
}
// Output: 1,2,3,4
mientras bucles
let x = 0
while(x < 5){
console.log(x)
x++
}
// Output: 1,2,3,4
hacer ... mientras bucles
let x = 0
do{
console.log(x)
x++
}while(x < 5)
// Output: 1,2,3,4
Hoy (18/12/2019) realizo prueba en mi v10.13.6 macOS (High Sierra), en Chrome v 79.0, v13.0.4 Safari y Firefox v71.0 (64 bits) - Conclusiones sobre la optimización (y micro-optimización de los cuales generalmente no vale la pena introducirlo en el código porque el beneficio es pequeño, pero la complejidad del código crece).
Parece que el tradicional for i
( Aa ) es una buena opción para escribir código rápido en todos los navegadores.
Las otras soluciones, como for-of
( Ad ), todas en el grupo C. ... suelen ser de 2 a 10 (y más) veces más lentas que Aa , pero para arreglos pequeños está bien usarlo, en aras de aumentar la claridad del código.
Los bucles con longitud de matriz en caché n
( Ab, Bb, Be ) son a veces más rápidos, a veces no. Probablemente los compiladores detectan automáticamente esta situación e introducen el almacenamiento en caché. Las diferencias de velocidad entre las versiones en caché y no en caché ( Aa, Ba, Bd ) son de aproximadamente ~ 1%, por lo que parece que introducir n
es una microoptimización .
Las i--
soluciones similares en las que el bucle comienza desde el último elemento de matriz ( Ac, Bc ) suelen ser ~ 30% más lentas que las soluciones directas; probablemente la razón sea la forma en que funciona la memoria caché de la CPU : la lectura de memoria directa es más óptima para el almacenamiento en caché de la CPU). Se recomienda NO UTILIZAR tales soluciones.
En las pruebas calculamos la suma de los elementos de la matriz. Realizo una prueba para matrices pequeñas (10 elementos) y matrices grandes (elementos 1M) y las divido en tres grupos:
for
pruebaswhile
pruebasResultados cruzados del navegador
Resultados para todos los navegadores probados
Matriz con 10 elementos.
Resultados para Chrome. Puede realizar la prueba en su máquina aquí .
Matriz con 1,000,000 de elementos
Resultados para Chrome. Puede realizar la prueba en su máquina aquí
Al iterar sobre una matriz, a menudo queremos lograr uno de los siguientes objetivos:
Queremos iterar sobre la matriz y crear una nueva matriz:
Array.prototype.map
Queremos iterar sobre la matriz y no crear una nueva matriz:
Array.prototype.forEach
for..of
lazo
En JavaScript, hay muchas formas de lograr ambos objetivos. Sin embargo, algunos son más convenientes que otros. A continuación puede encontrar algunos métodos de uso común (la IMO más conveniente) para lograr la iteración de matriz en JavaScript.
Map
map()
es una función ubicada en la 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 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 argumento paramap()
.
La diferencia distintiva entre map
y otro mecanismo de bucle como forEach
y un for..of
bucle es que map
devuelve una nueva matriz y deja intacta la matriz anterior (excepto si la manipula explícitamente con think like splice
).
Además, tenga en cuenta que la map
devolución de llamada de la función proporciona el número de índice de la iteración actual como un segundo argumento. Además, ¿el tercer argumento proporciona la matriz en la que map
se llamó? Algunas veces estas propiedades pueden ser muy útiles.
forEach
forEach
es una función en la Array.prototype
que se 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. A diferencia de la map()
función, 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 map
función, la forEach
devolución de llamada proporciona el número de índice de la iteración actual como un segundo argumento. Además, ¿el tercer argumento proporciona la matriz en la que forEach
se llamó?
for..of
El for..of
bucle 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 recorrer. Tenga en cuenta que el nombreelement
es arbitrario, y podríamos haber elegido cualquier otro nombre como 'el' o algo más declarativo cuando sea aplicable.
No confundas el for..in
bucle con el for..of
bucle. for..in
recorrerá todas las propiedades enumerables de la matriz, mientras que el for..of
ciclo 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);
}
forEach
y no solofor
. como se dijo, en C # fue un poco diferente, y eso me confundió :)i < len
yi++
puede hacerlo el motor, en lugar del intérprete.)