La única diferencia que veo en map y foreach es que map
devuelve una matriz y forEach
no. Sin embargo, ni siquiera entiendo la última línea del forEach
método " func.call(scope, this[i], i, this);
". Por ejemplo, no es " this
" y " scope
", en referencia al mismo objeto y no es this[i]
, y i
en referencia al valor de la corriente en el circuito?
Noté en otra publicación que alguien decía "Úselo forEach
cuando quiera hacer algo basándose en cada elemento de la lista. Puede que esté agregando cosas a la página, por ejemplo. Esencialmente, es ideal para cuando quiere" efectos secundarios ". No sé qué se entiende por efectos secundarios.
Array.prototype.map = function(fnc) {
var a = new Array(this.length);
for (var i = 0; i < this.length; i++) {
a[i] = fnc(this[i]);
}
return a;
}
Array.prototype.forEach = function(func, scope) {
scope = scope || this;
for (var i = 0, l = this.length; i < l; i++) {
func.call(scope, this[i], i, this);
}
}
Finalmente, ¿hay algún uso real para estos métodos en javascript (ya que no estamos actualizando una base de datos) además de manipular números como este?
alert([1,2,3,4].map(function(x){ return x + 1})); //this is the only example I ever see of map in javascript.
Gracias por cualquier respuesta.
fuente
map
yforEach
? Todo lo que obtengo de Google son especificaciones de uso y tutoriales.Respuestas:
La diferencia esencial entre
map
yforEach
en su ejemplo es queforEach
opera sobre los elementos originales de la matriz, mientrasmap
que como resultado devuelve explícitamente una nueva matriz.Con
forEach
usted está tomando alguna acción con, y opcionalmente cambiando, cada elemento en la matriz original. ElforEach
método ejecuta la función que proporcionas para cada elemento, pero no devuelve nada (undefined
). Por otro lado,map
recorre la matriz, aplica una función a cada elemento y emite el resultado como una nueva matriz .El "efecto secundario"
forEach
es que se está cambiando la matriz original. "Sin efectos secundarios" conmap
significa que, en el uso idiomático, los elementos originales de la matriz no se modifican; la nueva matriz es un mapeo uno a uno de cada elemento en el arreglo original - la transformación de mapeo es su función provista.El hecho de que no haya una base de datos involucrada no significa que no tendrá que operar con estructuras de datos, que, después de todo, es una de las esencias de la programación en cualquier lenguaje. En cuanto a su última pregunta, su matriz puede contener no solo números, sino también objetos, cadenas, funciones, etc.
fuente
.map
puede hacer todo lo que.forEach
puede hacer (incluida la modificación de elementos), solo devuelve una nueva lista construida a partir de la función del iterador..map()
crea una nueva matriz y no altera la original. De hecho, podría modificar la matriz que se está mapeando, pero eso sería al menos no idiomático, si no sin sentido..forEach()
, aunque similar, aplica su función a cada elemento, pero siempre devuelveundefined
. A pesar de todo lo anterior, el OP también está preguntando sobre sus propias funciones específicas agregadas al prototipo de matriz; no había ES5 aquí en el pasado.forEach
haga que no puedas hacermap
. Simplemente podría no importarle el valor de retorno demap
y tendría unforEach
. La diferencia es que es muy ineficaz de usarmap
para tareas en las que no desea crear una nueva matriz basada en los resultados. Entonces, para esos, usaforEach
.for
bucle antiguo . No estoy en desacuerdo con que haya alguna diferencia en la "eficacia", pero tampoco creo que nadie esté argumentando que uno tiene algo de magia que el otro no puede lograr de alguna manera. Aunque, de hecho, hay una cosa quemap
no se puede hacer: no devolver una matriz. No hay valor en tener JS altura de las expectativas de otros idiomas como el comportamiento de los favoritos funcionales comomap
,reduce
,filter
, etc. Por ejemplo, se podría poner en prácticareduceRight
el uso de bloques de construcción similares, pero por qué no sólo tiene que utilizarreduceRight
?b.val = b.val**2
dentro del objeto devuelto . Eso es exactamente lo que estamos diciendo que es posible, pero confuso y no idiomático. Normalmente, simplemente devuelve el nuevo valor, no lo asigna también a la matriz original:a=[{val:1},{val:2},{val:3},{val:4}]; a.map((b)=>{b.val**2}); JSON.stringify(a);
La principal diferencia entre los dos métodos es conceptual y estilística: se utiliza
forEach
cuando se quiere hacer algo con o con cada elemento de una matriz (creo que hacer "con" es lo que la publicación que cita significaba con "efectos secundarios") , mientras que usasmap
cuando quieres copiar y transformar cada elemento de una matriz (sin cambiar el original).Debido a que ambos
map
yforEach
llaman a una función en cada elemento de una matriz, y esa función está definida por el usuario, no hay casi nada que pueda hacer con uno y no con el otro. Es posible, aunque feo, usarlomap
para modificar una matriz en el lugar y / o hacer algo con elementos de la matriz:pero mucho más limpio y más obvio en cuanto a su intención de usar
forEach
:Especialmente si, como suele ser el caso en el mundo real,
el
es una variable útilmente legible por humanos:De la misma manera, puede usar fácilmente
forEach
para crear una nueva matriz:pero es más limpio de usar
map
:Tenga en cuenta también que, debido a que
map
crea una nueva matriz, es probable que incurre en al menos algún impacto de rendimiento / memoria cuando todo lo que necesita es iteración, particularmente para matrices grandes, consulte http://jsperf.com/map-foreachEn cuanto a por qué querría usar estas funciones, son útiles cada vez que necesita realizar una manipulación de matrices en javascript, que (incluso si solo estamos hablando de javascript en un entorno de navegador) es bastante frecuente, casi en cualquier momento está accediendo a una matriz que no está escribiendo a mano en su código. Es posible que esté tratando con una matriz de elementos DOM en la página, o datos extraídos de una solicitud AJAX, o datos ingresados en un formulario por el usuario. Un ejemplo común con el que me encuentro es extraer datos de una API externa, donde es posible que desee usar
map
para transformar los datos en el formato que desee y luego usarforEach
para iterar sobre su nueva matriz para mostrárselo a su usuario.fuente
.map()
todo el tiempo para modificar elementos en línea. Tenía la impresión de que era el principal beneficio de usar.map
over.forEach
.map
puede modificar elementos, sí, pero crearía una matriz que no necesita. También debe considerar cómo la elección de uno u otro permite que el lector adivinar si usted tiene o no efectos secundariosLa respuesta votada (de Ken Redler) es engañosa.
Un efecto secundario en informática significa que una propiedad de una función / método altera un estado global [wiki] . En un sentido estricto, esto también puede incluir la lectura de un estado global, en lugar de argumentos. En la programación imperativa o OO, los efectos secundarios aparecen la mayor parte del tiempo. Y probablemente lo esté utilizando sin darse cuenta.
La diferencia significativa entre
forEach
ymap
es quemap
asigna memoria y almacena el valor de retorno, mientras que loforEach
desecha. Ver especificaciones emca para obtener más información.En cuanto a la razón por la que la gente dice que
forEach
se usa cuando desea un efecto secundario, es que el valor de retorno deforEach
es siempreundefined
. Si no tiene ningún efecto secundario (no cambia el estado global), entonces la función solo está perdiendo el tiempo de la CPU. Un compilador de optimización eliminará este bloque de código y lo reemplazará con el valor final (undefined
).Por cierto, cabe señalar que JavaScript no tiene restricciones sobre los efectos secundarios. Todavía puede modificar la matriz original en el interior
map
.fuente
Esta es una hermosa pregunta con una respuesta inesperada.
Lo siguiente se basa en la descripción oficial de
Array.prototype.map()
.No hay nada que
forEach()
pueda hacer quemap()
no pueda. Es decir,map()
es un superconjunto estricto deforEach()
.Aunque
map()
generalmente se usa para crear una nueva matriz, también se puede usar para cambiar la matriz actual. El siguiente ejemplo lo ilustra:En el ejemplo anterior,
a
se configuró convenientementea[i] === i
parai < a.length
. Aun así, demuestra el poder demap()
y, en particular, su capacidad para cambiar la matriz en la que se llama.Nota 1:
La descripción oficial implica que
map()
incluso puede cambiar la longitud de la matriz en la que se llama. Sin embargo, no veo (una buena) razón para hacer esto.Nota 2:
Si bien el
map()
mapa es un superconjunto deforEach()
,forEach()
aún debe usarse cuando se desee el cambio de una matriz determinada. Esto aclara tus intenciones.Espero que esto haya ayudado.
fuente
mapped = a.map(function (x, i, arr) { arr[i] = x * x * x; return x * x; });.
a.forEach(function(x, i, arr) { ...
, lo cual, nuevamente, es una forma conceptualmente más correcta cuando existe la intención de mutar cada elemento original en lugar de asignar valores de una matriz a otraPuede usarlo
map
como si lo fueraforEach
.Sin embargo, hará más de lo necesario.
scope
puede ser un objeto arbitrario; de ninguna manera es necesariamentethis
.En cuanto a si hay usos reales para
map
yforEach
, también preguntar si hay usos reales parafor
owhile
bucles.fuente
scope = scope || this
significa "siscope
es falso (indefinido, nulo, falso, etc.) establecer el alcance en en suthis
lugar y continuar".Si bien todas las preguntas anteriores son correctas, definitivamente haría una distinción diferente. El uso de
map
yforEach
puede implicar intención.Me gusta usar
map
cuando simplemente estoy transformando los datos existentes de alguna manera (pero quiero asegurarme de que los datos originales no cambien.Me gusta usar
forEach
cuando modifico la colección en su lugar.Por ejemplo,
Mi regla general es asegurarme de que
map
siempre está creando un nuevo objeto / valor para devolver para cada elemento de la lista de origen y devolverlo en lugar de simplemente realizar alguna operación en cada elemento.A menos que tenga una necesidad real de modificar la lista existente, realmente no tiene sentido modificarla en su lugar y encaja mejor en estilos de programación funcionales / inmutables.
fuente
TL; respuesta DR -
map siempre devuelve otra matriz.
forEach no lo hace. Depende de usted decidir qué hace. Devuelva una matriz si lo desea o haga otra cosa si no lo desea.
La flexibilidad es deseable en determinadas situaciones. Si no es por lo que está tratando, use map.
fuente
Una vez más, me siento como un nigromante agregando una respuesta a una pregunta que se hizo hace 5 años (felizmente hay actividad bastante reciente, así que no soy el único que está molestando a los muertos :).
Otros ya han publicado sobre su pregunta principal sobre la diferencia entre las funciones. Pero para...
... es gracioso que preguntes. Hoy mismo escribí un fragmento de código que asigna una cantidad de valores de una expresión regular a múltiples variables usando map para la transformación. Se usó para convertir una estructura basada en texto muy complicada en datos visualizables ... pero en aras de la simplicidad, ofreceré un ejemplo usando cadenas de fecha, porque probablemente sean más familiares para todos (aunque, si mi problema hubiera sido realmente con las fechas , en lugar de map, habría usado Date-object, que habría hecho el trabajo espléndidamente por sí solo).
Entonces ... si bien esto fue solo un ejemplo, y solo hizo una transformación muy básica para los datos (solo por ejemplo) ... haber hecho esto sin mapa hubiera sido una tarea mucho más tediosa.
Por supuesto, está escrito en una versión de JavaScript que no creo que muchos navegadores admitan todavía (al menos completamente), pero estamos llegando allí. Si tuviera que ejecutarlo en el navegador, creo que se transpilaría muy bien.
fuente