Array.map ne semble pas fonctionner sur des tableaux non initialisés

J'essaie de définir des valeurs par défaut sur un tableau non initialisé à l'aide de la fonction de carte, mais cela ne semble pas fonctionner, des idées sur la façon de définir des valeurs par défaut?

Considérons cet extrait de code que j'ai essayé dans la console Chrome.

> var N = 10; > var x = new Array(N); > x [undefined x 10] > x.map(function(i) { return 0;}); [undefined x 10] 

Je m'attendais à ce que le tableau soit initialisé à 0.

Si vous souhaitez remplir un tableau, vous pouvez le faire

 Array.apply(null, new Array(5)).map(function() { return 0; }); // [ 0, 0, 0, 0, 0 ] 

Après avoir lu un des messages liés dans les commentaires , j'ai trouvé que cela peut aussi être écrit comme

 Array.apply(null, {length: 5}).map(function() { return 0; }); 

Cependant, essayer d'utiliser .map sur des valeurs indéfinies ne fonctionnera pas.

 x = new Array(10); x.map(function() { console.log("hello"); }); // so sad, no "hello" // [ , , , , , , , , , ] 

.map sautera des valeurs indéfinies 🙁

C'est la façon dont il est décrit par la spécification de langue ECMAScript

Voici la partie pertinente de Array.prototype.map , comme décrit par ( §15.4.4.19 )

  • 8 . Répétez, alors que k < len
    • A) Soit Pk ToString(k) .
    • B) Soit kPresent le résultat d'appeler la méthode interne [O [HasProperty]] de O avec l'argument Pk .
    • C) Si kPresent est true , alors
      • Faire la magie

Étant donné qu'il n'y a pas de membre intime dans votre tableau, appeler par exemple une new Array (1337).hasOwnProperty (42) évalué comme false , donc la condition à l'étape 8.c n'est pas respectée.

Vous pouvez cependant utiliser un petit "hack" pour faire ce que vous voulez.

Array.apply(null, { length: 5 }).map(Number.call, Number) //[0, 1, 2, 3, 4]

La façon dont cela fonctionne a été explicitement expliquée par @Zirak

J'aimerais simplement souligner que vous pouvez maintenant:

 new Array(2).fill(null).map(x => 4); 

Cela renverra [4, 4] .

La fonction .map() ignore les entrées qui n'ont jamais été affectées de valeurs. Ainsi, sur un tableau nouvellement construit comme le vôtre, il ne fait essentiellement rien.

Voici la description de MDN.

Avec .map() , les éléments indéfinis sont ignorés et ne sont pas transmis au rappel, donc, si vous disposez d'un tableau sans éléments qui contiennent quelque chose, le rappel n'est jamais appelé.

À partir du script ECMA 262, spécification 5.1 , section 15.4.4.19:

Callbackfn est appelé uniquement pour les éléments du tableau qui existent réellement; Il n'est pas demandé l'absence d'éléments du tableau.

Vous pouvez remplir un tableau avec des zéros en utilisant cette fonction :

 function fillArrayWithNumber(n) { var arr = Array.apply(null, Array(n)); return arr.map(function (x, i) { return 0; }); } fillArrayWithNumber(5); // [0,0,0,0,0] 

Ou avec un petit changement, vous pouvez utiliser des index à la place:

 function fillArrayWithIndex(n) { var arr = Array.apply(null, Array(n)); return arr.map(function (x, i) { return i; }); } fillArrayWithIndex(5); // [0,1,2,3,4] 

Violon

S'appuyant sur une réponse précédente, il existe une nouvelle syntaxe plus courte. L'OP voulait créer un tableau de N éléments initialisés avec 0.

 var N = 10; var x = new Array(N).fill(0); // x is now: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 

Vous n'avez pas non plus besoin du new – c'est facultatif dans ce contexte.

Vérifiez la compatibilité de votre plate – forme cible et / ou utilisez un pollyfill s'il n'est pas disponible.