2015-02-09 22 views
9

Qual è esattamente la differenza tra:Differenza tra Array.apply (null, Array (x)) e Array (x)

Array(3) 
// and 
Array.apply(null, Array(3)) 

Il primo rendimenti [undefined x 3] mentre la seconda restituisce [undefined, undefined, undefined]. Il secondo è concatenabile tramite Array.prototype.functions come .map, ma il primo non lo è. Perché?

+0

'Array.apply (null, Array (9))' * non * 'new Array (9) '. Sta diffondendo un 'Array (9)' in 'Array()' come nove parametri. Anche se funziona, è praticamente il modo sbagliato. Ad esempio puoi 'new Array (1e7)' ma non 'Array.apply (null, Array (1e7))'. – Sheepy

+1

correlate: http://stackoverflow.com/questions/22949976/why-does-array-applynull-args-act-inconsistently-when-dealing-with-sparse-a – Sheepy

risposta

13

C'è una differenza, piuttosto significativa.

Il Array costruttore sia accetta un singolo numero, dando la lunghezza della matrice, e si crea un array con indici "vuoti", o più correttamente la lunghezza è impostata ma l'allineamento in realtà non contiene nulla

Array(3); // creates [], with a length of 3 

Quando si chiama il costruttore matrice con un numero come unico argomento, si crea una matrice che è vuota, e che non può essere iterato con i soliti metodi Array.

O ... la costruzione Array accetta diversi argomenti, mentre viene creato un array in cui ogni argomento è un valore nella matrice

Array(1,2,3); // creates an array [1,2,3] etc. 

Quando si chiama questo

Array.apply(null, Array(3)) 

Diventa un po 'più interessante.

apply accetta il valore this come primo argomento, e come non è utile qui, è impostato per null

La parte interessante è il secondo argomento, dove un array vuoto viene passato in.
Come apply accetta un array sarebbe come chiamare

Array(undefined, undefined, undefined); 

e che crea un array con tre indici che non è vuota, ma hanno il valore effettivamente impostato undefined, ed è per questo ca n essere iterato sopra.

TL; DR
La differenza principale è che Array(3) crea un array con tre indici che sono vuoti. In realtà, non esistono realmente, l'array ha solo una lunghezza di 3.

Passando in tale array con indici vuoti al costruttore Array utilizzando apply è lo stesso facendo Array(undefined, undefined, undefined);, che crea un array con tre undefined indici, e undefined è infatti un valore, quindi non vuota come nel primo esempio.

I metodi di array come map() possono solo scorrere sui valori effettivi, non sugli indici vuoti.

0

Perché il primo array non ha le proprietà ordinate arr[0] === undefined e il secondo fa.Array funziona come forEach e map eseguirà iterazioni da 0 alla lunghezza dell'array - 1 e la mancanza di ordine per le proprietà del primo è un problema. La seconda versione produce un array con l'ordine corretto, cioè

arr = Array.apply(null, Array(3)); 
arr[0] === undefined //true 
arr[1] === undefined //true 
//etc. 

la prima versione come notato non. Inoltre, aggiungere new alla prima versione non funzionerebbe.

11

Il .map() API non un'iterazione su elementi di matrice completamente inizializzati. Quando si effettua una nuova matrice con il costruttore new Array(n), si ottiene un array con il .length che hai chiesto, ma con elementi inesistenti che devono essere saltati con metodi come .map().

L'espressione Array.apply(null, Array(9)) popola esplicitamente l'istanza dell'array appena creata con undefined, ma è sufficiente. Il trucco è se l'operatore in segnalerà o meno che l'array contiene un elemento nell'indice specificato. Cioè:

var a = new Array(9); 
alert(2 in a); // alerts "false" 

Questo perché non c'è davvero alcun elemento nella posizione 2 nella matrice. Ma:

var a = Array.apply(null, Array(9)); 
alert(2 in a); // alerts "true" 

La chiamata esterna alla costruzione Array avrà esplicitamente popolato gli elementi.

+0

Grazie per la risposta, non ero davvero sicuro che ciò che era "in" ogni slot non era lo stesso del valore indefinito, poiché l'indicizzazione in una determinata posizione restituisce un valore indefinito. –

+1

@ mb_s88 considerano '0 in Array (9); // false' –

+0

@ mb_s88 risposta esteso un po ' – Pointy

3

Si tratta di un manufatto di come applicare opere. Quando si esegue:

new Array(9) 

un array vuoto viene creato con una lunghezza di 9. mappa non visita i membri inesistenti, così fa nulla. Tuttavia, apply trasforma la matrice in un elenco tramite CreateListFromArrayLike quindi trasforma l'array precedentemente vuoto in un elenco di parametri come:

[undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined]; 

che viene passato Array per creare un array con 9 membri, tutte del valore di undefined. Quindi ora la mappa li visiterà tutti.

BTW, ECMAScript 2015 ha Array.prototype.fill per questo (vedi anche MDN) in modo da poter fare:

Array(9).fill(0); 
Problemi correlati