¿Qué está haciendo .map () en esta situación?

95

Usando la consola de Chrome, esta es mi entrada y salida:

[0].map(Array);

[[0, 0, [0]]]; // output

¿Que está sucediendo aquí?

EDITAR

La razón por la que esto me da curiosidad es porque algo como

[0].map(String);

Volverá

["0"];

Y no

["0", "0", "String"]
Jacksonkr
fuente
34
Supongo que porque siempre necesita algunos WTF de Javascript para sentirse feliz
npst
12
Oh, es solo una variante menos wtf-y de['10', '10', '10'].map(parseInt)
gronostaj
2
Otro .map()comportamiento extraño : stackoverflow.com/questions/14528397/… En general, debes tener cuidado al usar .map()funciones que toman más de un argumento.
Barmar
2
Solo hazlo[0].map(console.log)
Bergi
1
@Jacksonkr: Gracias por la respuesta. Creo que fue así: escribí un comentario, explicando que ver JS WTFs me hace feliz, no tengo que usar el lenguaje a menudo. Alguien me preguntó por qué miraría las preguntas de JS si no me gusta el idioma. npst respondió y se eliminaron los dos primeros comentarios. Es gracioso que su comentario aún reciba votación, sí.
Eric Duminil

Respuestas:

123

La .map()función llama a la Array()función con tres argumentos, el valor del elemento de la matriz que es 0, el índice de ese elemento, también 0, y una referencia a toda la matriz.

Entonces es como hacer esto:

var a = [0];
var index = 0
Array(a[index], index, a);   // create array with three elements

La matriz devuelta por Array()entonces se convierte en el primer elemento de la matriz que .map()crea, de ahí el nivel adicional de anidación en su [[0, 0, [0]]]resultado.

EDITAR con respecto a su edición: cuando dice [0].map(String);que resulta en String()ser llamado con los mismos tres argumentos como String(a[index], index, a), pero la String()función ignora todos menos el primer argumento, mientras que Array()usa todos los argumentos proporcionados.

nnnnnn
fuente
39

En primer lugar , Arraypodría usarse como una función para crear matrices:

var arr = Array(1, 2, "Hello");

console.log(arr); // [1, 2, "Hello"]

En segundo lugar , mappasa tres parámetros a su devolución de llamada: el elemento, su índice de la matriz y la propia matriz.

Entonces , dado que su matriz contiene un elemento, la línea:

[0].map(Array);

es equivalente a:

[Array(0, 0, [0])];     // the element 0 in the original array will be mapped into Array(0, 0, [0])
ibrahim mahrir
fuente
6

Después de actualizar la pregunta. Otras respuestas le brindan información sobre el mapa

Para responder por qué la matriz y la cadena difieren en los constructores

El constructor de cadenas acepta 1 parámetro String (cosa) mientras que la matriz nueva Array (elemento0, elemento1 [, ... [, elementoN]])

Volodymyr Bilyachat
fuente
2
Es la misma razón por la que .map(Number)convierte cada artículo en un número en lugar de devolver algo como [3, 2, [4, 1, 3]]para cada artículo.
user4642212
@Xufox sí, la respuesta está en constructores :)
Volodymyr Bilyachat
4

Esta llamada

[0].map(Array);

le da el mismo resultado que si escribiera algo como esto:

[0].map(function (value, index, array) {
    return Array(value, index, array);
})

La función de mapa llama a la función Array con tres parámetros: valor del elemento, índice del elemento y matriz completa. Esta llamada a Arraydevuelve su matriz con 3 elementos: valor (número 0), índice (número 0), matriz completa ( [0]).

Y esta nueva matriz está envuelta en la matriz original, porque asignó el elemento original (número 0) al nuevo elemento (matriz de 3 elementos)

Nota: Es posible que esté acostumbrado a usar solo el primer parámetro como en

array.map(function (a) { return a * a; });

o usando solo dos para obtener también el índice

array.map(function (item, index) { return "index=" + index + ", value=" + item; });

Pero debe recordar que mapaún proporciona 3 parámetros, simplemente ignórelos en su función de devolución de llamada. Esa también es la razón por la que un código como:

[0].map(String);

devoluciones

["0"]

Es porque la función String se preocupa solo por el primer parámetro e ignora otros parámetros pasados. Si llamas

String(11, "Some", "other", "ignored", "parameters")

todavía obtendrás

"11"
Mariusz Pawelski
fuente