2012-06-29 16 views
20

considerare:valori non definiti in Array (LEN) initializer

var a = Array(3); 
var b = [undefined,undefined,undefined]; 

Qual è la ragione per cui a.map e b.map producono risultati diversi?

a.map(function(){ return 0; }); //produces -> [undefined,undefined,undefined] 
b.map(function(){ return 0; }); //produces -> [0,0,0] 
+1

correlati: verificare che cosa accade se si imposta 'b.length = 5;' prima di eseguire il 'map':' [0, 0, 0, non definito, non definito] ' – apsillers

risposta

23

Il costruttore di array crea una matrice con la lunghezza specificata. Lo fa non crea le chiavi. La funzione di callback di Array.prototype.map viene eseguita solo per gli elementi nell'elenco.
Cioè, tutti i valori che sono associati con una chiave (numero intero) 0 ≤ i < lunghezza.

  • Array(3) ha zero chiavi, così richiamata .map s' è mai attivato.
  • [void 0, void 0, void 0] ha tre chiavi, per le quali viene eseguita la funzione di richiamata.

    Array(3).hasOwnProperty(0);     // false 
    [void 0, void 0, void 0].hasOwnProperty(0); // true 
    

La specifica e la sua polyfill sono menzionati in MDN. Alla riga 47, if (k in O) { mostra che le chiavi inesistenti non sono trattate dalla funzione di callback.

+1

In realtà, mappa dovrebbe iterare non oltre i tasti, ma sulla sequenza di valori 0..array.length-1 –

+0

@ panda-34 Saltare i tasti tra 0 e n è simile al passaggio sui tasti numerici. Ma sei corretto, a rigor di termini, avrei dovuto dirlo;) –

+0

@RobW Possiamo supporre che 'Array (3)' non * assegni realmente memoria * per memorizzare elementi '3', quali valori sono' indefiniti' e imposta semplicemente la proprietà 'length' a' 3', giusto? – Engineer

4

a è un array vuoto che non ha elementi, così cartina funzione produce array vuoto senza elementi (per specifiche, carta produce risultati solo se [[hasProperty]] è vero.)b è un array di tre elementi, quindi map produce un array di tre elementi.

6

Da MDN:

callback viene invocata solo per gli indici dell'array che hanno assegnato valori; non è invocato per gli indici che sono stati cancellati o che non sono mai stati assegnati valori a .

Per l'array a, è stato istanziato un array di lunghezza 3 ma non sono stati assegnati valori. La funzione mappa non trova elementi con valori assegnati, quindi non produce un nuovo array.

Per l'array b, è stata creata un'istanza di un array di 3 elementi, ciascuno con il valore undefined. La funzione mappa trova 3 elementi con valori assegnati e restituisce '0' come nuovo valore per ognuno di essi in un nuovo array.

3

map solo itera le proprietà esistenti, non gli indici vuoti.

Pertanto, se si desidera che funzioni, è necessario prima riempire l'array.

Ci sono diversi modi per farlo, ad esempio:

  • .fill(), introdotto nel ES6

    console.log(new Array(3).fill().map(function(){ return 0; }));

  • chiamata concat con apply:

    var arr = [].concat.apply([], new Array(3)); 
     
    console.log(arr.map(function(){ return 0; }));

  • Un vecchio for loop.

    var arr = new Array(3); 
     
    for(var i=0; i<arr.length; ++i) arr[i] = 1; /* whatever */ 
     
    console.log(arr.map(function(){ return 0; }));

  • Usa qualche idea da Most efficient way to create a zero filled JavaScript array?

  • Etcetera.

Problemi correlati