es6 - foreach javascript object
¿Qué uso tiene el javascript forEach método(que el mapa no puede hacer)? (8)
Esta es una bella 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 que map()
no pueda. Es decir, map()
es un súper conjunto estricto de forEach()
.
Aunque map()
se usa generalmente para crear una nueva matriz, también se puede usar para cambiar la matriz actual. El siguiente ejemplo lo ilustra:
var a = [0, 1, 2, 3, 4], mapped = null;
mapped = a.map(function (x) { a[x] = x*x*x; return x*x; });
console.log(mapped); // logs [0, 1, 4, 9, 16] As expected, these are squares.
console.log(a); // logs [0, 1, 8, 27, 64] These are cubes of the original array!!
En el ejemplo anterior, a
se configuró convenientemente de modo que a[i] === i
para i < a.length
. Aun así, demuestra el poder de map()
y, en particular, su capacidad para cambiar la matriz a la que se llama.
Nota 1:
La descripción oficial implica que map()
puede incluso cambiar la longitud de la matriz en la que se llama. Sin embargo, no puedo ver (una buena) razón para hacer esto.
Nota 2:
Mientras que map()
map es un superconjunto de forEach()
, forEach()
debería seguir utilizándose cuando se desee cambiar una matriz determinada. Esto hace que tus intenciones sean claras.
Espero que esto haya ayudado.
La única diferencia que veo en el mapa y en foreach es que el map
está devolviendo una matriz y para cada forEach
no. Sin embargo, ni siquiera entiendo la última línea del método forEach
" func.call(scope, this[i], i, this);
". Por ejemplo, ¿no se refieren " this
" y " scope
" al mismo objeto y no es this[i]
y i
refiriéndome al valor actual en el ciclo?
Noté en otra publicación que alguien dijo "Use forEach
cuando quieras hacer algo sobre la base de cada elemento de la lista. Por ejemplo, podrías agregar cosas a la página. Básicamente, es ideal para cuando quieres" 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) que no sea para 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.
La diferencia esencial entre map
y forEach
en su ejemplo es que forEach
opera en los elementos de la matriz original, mientras que map
devuelve explícitamente una nueva matriz como resultado.
Con forEach
usted está tomando alguna acción con, y opcionalmente cambiando, cada elemento en la matriz original. El método forEach
ejecuta la función que proporciona para cada elemento, pero no devuelve nada ( undefined
). Por otro lado, el map
recorre la matriz, aplica una función a cada elemento y emite el resultado como una nueva matriz .
El "efecto secundario" con forEach
es que se está cambiando la matriz original. "Sin efecto secundario" con el map
significa que, en el uso idiomático, los elementos de la matriz original no se modifican; la nueva matriz es un mapeo uno a uno de cada elemento en la matriz 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 deba operar estructuras de datos, que, después de todo, es una de las esencias de la programación en cualquier idioma. En cuanto a su última pregunta, su matriz puede contener no solo números, sino también objetos, cadenas, funciones, etc.
La diferencia principal entre los dos métodos es conceptual y estilística: forEach
vez que quieres hacer algo con cada elemento de una matriz (hacer "con" es lo que la publicación que citas significa "efectos secundarios", creo ), mientras que utiliza el map
cuando quiere copiar y transformar cada elemento de una matriz (sin cambiar el original).
Debido a que tanto map
como forEach
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 una y no con la otra. Es posible, aunque feo, usar un map
para modificar una matriz en el lugar y / o hacer algo con los elementos de la matriz:
var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.map(function(el) {
el.val++; // modify element in-place
alert(el.val); // do something with each element
});
// a now contains [{ val: 2 }, { val: 3 }, { val: 4 }]
pero mucho más limpio y más obvio en cuanto a su intención de usar para forEach
:
var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.forEach(function(el) {
el.val++;
alert(el.val);
});
Especialmente si, como suele ser el caso en el mundo real, el
es una variable útil legible por el ser humano:
cats.forEach(function(cat) {
cat.meow(); // nicer than cats[x].meow()
});
De la misma manera, puedes usar fácilmente para cada forEach
para hacer una nueva matriz:
var a = [1,2,3],
b = [];
a.forEach(function(el) {
b.push(el+1);
});
// b is now [2,3,4], a is unchanged
pero es más limpio usar el map
:
var a = [1,2,3],
b = a.map(function(el) {
return el+1;
});
Tenga en cuenta también que, debido a que el map
crea una nueva matriz, es probable que tenga al menos algo de rendimiento / memoria cuando todo lo que necesita es iteración, particularmente para matrices grandes: consulte http://jsperf.com/map-foreach
En cuanto a por qué querrías usar estas funciones, son útiles siempre que necesites manipular las matrices en JavaScript, lo cual (incluso si solo estamos hablando de javascript en un entorno de navegador) es muy a menudo, casi en cualquier momento. está accediendo a una matriz que no está escribiendo a mano en su código. Puede tratar 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 que encuentro es extraer datos de una API externa, donde es posible que desee utilizar un map
para transformar los datos en el formato que desea y luego usar forEach
para iterar sobre su nueva matriz para mostrarla a su usuario.
La respuesta votada (de Ken Redler) es engañosa.
Un efecto secundario en la ciencia de la computación significa que una propiedad de una función / método altera un estado global [wiki] . En cierto sentido, esto también puede incluir leer desde un estado global, en lugar de desde argumentos. En la programación imperativa o OO, los efectos secundarios aparecen la mayor parte del tiempo. Y probablemente lo estés usando sin darte cuenta.
La diferencia significativa entre forEach
y el map
es que el map
asigna memoria y almacena el valor de retorno, mientras que forEach
lo descarta. Ver especificaciones de emca para más información.
En cuanto a la razón por la que la gente dice que forEach
se usa, cuando se desea un efecto secundario, el valor de retorno de forEach
siempre está undefined
. Si no tiene ningún efecto secundario (no cambia el estado global), entonces la función solo está desperdiciando 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, debe tenerse en cuenta que JavaScript no tiene restricciones sobre los efectos secundarios. Aún puede modificar la matriz original dentro del map
.
var a = [1,2,3]; //original
var b = a.map( function(x,i){a[i] = 2*x; return x+1} );
console.log("modified=%j/nnew array=%j",a,b);
// output:
// modified=[2,4,6]
// new array=[2,3,4]
Puedes usar el map
como si fuera para forEach
.
Sin embargo, hará más de lo necesario.
scope
puede ser un objeto arbitrario; de ninguna manera es necesariamente this
.
En cuanto a si hay usos reales para map
y forEach
, también para preguntar si hay usos reales para for
o while
bucles.
Respuesta de TL; DR
el mapa siempre devuelve otra matriz.
porque cada uno no. Depende de usted decidir lo que hace. Devuelve una matriz si quieres o haz otra cosa si no lo haces.
La flexibilidad es deseable es ciertas situaciones. Si no es por lo que estás tratando, utiliza el mapa.
Si bien todas las preguntas anteriores son correctas, definitivamente haré una distinción diferente. El uso de map
y forEach
puede implicar intento.
Me gusta usar el map
cuando simplemente estoy transformando los datos existentes de alguna manera (pero quiero asegurarme de que los datos originales no se modifiquen).
Me gusta utilizar forEach
cuando estoy modificando la colección en su lugar.
Por ejemplo,
var b = [{ val: 1 }, { val: 2 }, { val: 3 }];
var c = b.map(function(el) {
return { val: el.val + 1 }; // modify element in-place
});
console.log(b);
// [{ val: 1 }, { val: 2 }, { val: 3 }]
console.log(c);
// [{ val: 3 }, { val: 4 }, { val: 5 }]
Mi regla general es asegurarse de que al map
siempre esté creando un nuevo objeto / valor para devolver para cada elemento de la lista fuente y devolverlo en lugar de solo 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 se adapta mejor a los estilos de programación funcional / inmutable.
Una vez más, me siento como un nigromante que agrega una respuesta a una pregunta que se me formuló hace 5 años (afortunadamente hay actividad bastante reciente, así que no soy el único que molesta a los muertos :).
Otros ya han publicado sobre su pregunta principal con respecto a la diferencia entre las funciones. Pero para...
¿Hay algún uso real para estos métodos en javascript (ya que no estamos actualizando una base de datos) que no sea para manipular números como este?
... es gracioso que deberías preguntar Justo hoy escribí un fragmento de código que asigna una cantidad de valores de una expresión regular a múltiples variables usando el mapa para la transformación. Se usó para convertir una estructura basada en texto muy complicada en datos visualizables ... pero, por simplicidad, ofreceré un ejemplo usando cadenas de fechas, porque probablemente sean más familiares para todos (aunque si mi problema hubiera sido con fechas) , en vez del mapa, hubiera usado Date-object, lo que habría hecho el trabajo espléndidamente por sí mismo).
const DATE_REGEXP = /^(/d{4})-(/d{2})-(/d{2})T(/d{2}):(/d{2}):(/d{2})/.(/d{3})Z$/;
const TEST_STRING = ''2016-01-04T03:20:00.000Z'';
var [
iYear,
iMonth,
iDay,
iHour,
iMinute,
iSecond,
iMillisecond
] = DATE_REGEXP
// We take our regular expression and...
.exec(TEST_STRING)
// ...execute it against our string (resulting in an array of matches)...
.slice(1)
// ...drop the 0th element from those (which is the "full string match")...
.map(value => parseInt(value, 10));
// ...and map the rest of the values to integers...
// ...which we now have as individual variables at our perusal
console.debug(''RESULT =>'', iYear, iMonth, iDay, iHour, iMinute, iSecond, iMillisecond);
Entonces ... aunque esto fue sólo un ejemplo, y solo se realizó una transformación muy básica de los datos (solo por el ejemplo) ... haber hecho esto sin un mapa hubiera sido una tarea mucho más tediosa.
De acuerdo, está escrito en una versión de JavaScript que aún no creo que muchos navegadores admitan (al menos por completo), pero estamos llegando. Si tuviera que ejecutarlo en el navegador, creo que se traduciría muy bien.