Que fait .map () dans cette situation?

95

En utilisant la console Chrome, voici mon entrée et ma sortie:

[0].map(Array);

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

Que se passe-t-il ici?

ÉDITER

La raison pour laquelle cela me rend curieux est que quelque chose comme

[0].map(String);

Reviendra

["0"];

Et pas

["0", "0", "String"]
Jacksonkr
la source
34
Je suppose parce qu'il a toujours besoin de WTF Javascript pour se sentir heureux
npst
12
Oh, c'est juste une variante moins wtf-y de['10', '10', '10'].map(parseInt)
gronostaj
2
Autre .map()comportement étrange : stackoverflow.com/questions/14528397/ ... En général, vous devez être prudent lorsque vous utilisez .map()des fonctions qui prennent plus d'un argument.
Barmar
2
Just do[0].map(console.log)
Bergi
1
@Jacksonkr: Merci pour la réponse. Je pense que ça s'est passé comme ça: j'ai écrit un commentaire, expliquant que voir des JS WTF me rend heureux de ne pas avoir à utiliser souvent la langue. Quelqu'un a demandé pourquoi je regarderais les questions JS si je n'aime pas la langue. npst a répondu et les deux premiers commentaires ont été supprimés. C'est drôle que son commentaire soit toujours voté, oui.
Eric Duminil

Réponses:

123

La .map()fonction appelle la Array()fonction avec trois arguments, la valeur de l'élément de tableau qui est 0, l'index de cet élément, également 0, et une référence à l'ensemble du tableau.

Donc c'est comme faire ça:

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

Le tableau renvoyé par Array()devient alors le premier élément du tableau qui .map()crée, d'où le niveau supplémentaire d'imbrication dans votre [[0, 0, [0]]]résultat.

EDIT concernant votre modification: lorsque vous dites [0].map(String);que cela entraîne String()un appel avec les trois mêmes arguments comme String(a[index], index, a), mais la String()fonction ignore tout sauf le premier argument, alors qu'elle Array()utilise tous les arguments fournis.

nnnnnn
la source
39

Tout d'abord , Arraypourrait être utilisé comme une fonction pour créer des tableaux:

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

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

Deuxièmement , mappasse trois paramètres à son rappel: l'élément, son index du tableau et le tableau lui-même.

Donc , puisque votre tableau contient un élément, la ligne:

[0].map(Array);

est équivalent à:

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

Après avoir mis à jour la question. D'autres réponses vous fournissent des informations sur la carte

Pour expliquer pourquoi tableau et chaîne diffèrent, regardez les constructeurs

Le constructeur de chaînes accepte 1 paramètre String (chose) pendant que le tableau est nouveau Array (élément0, élément1 [, ... [, élémentN]])

Volodymyr Bilyachat
la source
2
C'est la même raison pour laquelle .map(Number)convertit chaque élément en un nombre plutôt que de renvoyer quelque chose comme [3, 2, [4, 1, 3]]pour chaque élément.
user4642212
@Xufox oui la réponse est dans les constructeurs :)
Volodymyr Bilyachat
4

Cet appel

[0].map(Array);

vous donne le même résultat que si vous écriviez quelque chose comme ceci:

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

La fonction de carte appelle la fonction Array avec trois paramètres: valeur de l'élément, index de l'élément et tableau entier. Cet appel à Arrayrenvoie votre tableau avec 3 éléments: valeur (nombre 0), index (nombre 0), tableau entier ( [0]).

Et ce nouveau tableau est enveloppé dans le tableau d'origine, car vous avez mappé l'élément d'origine (numéro 0) sur le nouvel élément (tableau de 3 éléments)

Remarque: vous pouvez être habitué à n'utiliser que le premier paramètre comme dans

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

ou en utilisant seulement deux pour obtenir également l'index

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

Mais vous devez vous rappeler que mapfournit toujours 3 paramètres que vous ignorez simplement dans votre fonction de rappel. C'est aussi la raison pour laquelle un code comme:

[0].map(String);

Retour

["0"]

C'est parce que la fonction String ne se soucie que du premier paramètre et ignore les autres paramètres passés. Si vous appelez

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

vous obtiendrez toujours

"11"
Mariusz Pawelski
la source