2016-05-27 12 views
5

Voglio costruire rapidamente un array di n lunghezza utilizzando il costruttore di array Array() e quindi eseguire il loop sull'array risultante.Utilizzare forEach per eseguire il loop su Array (n), matrice di valori non definiti

Per MDN's docs:

Se l'unico argomento passato al costruttore Array è un intero tra 0 e 2 -1 (compreso), questa restituisce un nuovo array JavaScript con lunghezza impostata quel numero. Se l'argomento è qualsiasi altro numero, viene generata un'eccezione RangeError .

Presumibilmente, l'esecuzione di Array(5) crea una matrice con una lunghezza di 5, che esegue.

var arr = new Array(5); 
 

 
console.log(arr); // [undefined x 5] 
 
console.log(arr.length); // 5

Tuttavia, quando provo ad anello sulla matrice risultante e disconnetterò i valori o l'indice, non succede nulla.

arr.forEach(function(v, i) { console.log(v, i); }); 

// nothing logs to the console 

In alternativa, se uso un array letterale, e cerco di ciclo sui valori, si registra come previsto:

[undefined, undefined].forEach(function(v, i) { console.log(v, i); }); 
 

 
// undefined 0 
 
// undefined 1

Perché non è possibile ciclare su una matrice creata dal costruttore Array?


This answer spiega alcune delle stranezze del browser che si verifica con map, ad esempio:

arr.map(function(v, i) { return i; }) // returns [undefined x 5] 

Ma io sono particolarmente interessato perché il ciclo forEachnon iterare affatto il valori.

+0

'[,,] foreach (console.log.bind (console, 'Log:'))' inoltre sembra rotto :) –

+0

Ma 'Array.apply (null, nuova Array (5)). ForEach (console.log.bind (console)) 'ok –

+0

È uguale a [JavaScript" new Array (n) "e" Array.prototype.map "weirdness] (http: // stackoverflow .com/q/5501581/1529630), ma con 'forEach'. – Oriol

risposta

4

Capisco che non rispondo direttamente alla domanda, ma credo che questo fornisca buone informazioni.

Check what Kyle Simpson said recently about this topic.

Fondamentalmente,

console.log(new Array(5)) // Chrome: [undefinedx5] Firefox: [ <5 empty slots> ] 

e

console.log([undefined, undefined, undefined, undefined, undefined]) // [ undefined, undefined, undefined, undefined, undefined ] 

sono completamente diversi tipi di valore. E il browser ti sta mentendo quando dice undefinedx5. L'applicazione di .map() sul primo caso non restituirà nulla, mentre nel secondo caso è possibile eseguire operazioni con undefined.

Dalla specifica, ecma-262/5.1/#sec-15.4.2.2, l'unica cosa che new Array(5) è, è creare un oggetto di tipo classe Array con proprietà length = 5. La sintassi di matrice letterale, [], posiziona effettivamente i tipi (se gli dai qualcosa) nelle slot.

+0

non puoi aggiungere qui una breve spiegazione su ciò che dice? –

+0

Se si usa 'JSON.stringify()' sul nuovo oggetto Array, si dovrebbe ottenere una sequenza di null. Penso che sia degno di nota. –

2

Sembra che tu abbia un errore di battitura nel codice:

arr.forEach(functio(v, i) { 

Utilizzare questo invece:

arr.forEach(function(v, i) { 

UPDATE

foreach() esegue la richiamata forniti una volta per ogni elemento presente nell'array in ordine crescente. Non viene invocato per le proprietà dell'indice che sono state eliminate o non inizializzate (ad esempio su array sparsi). MDN article

+0

Scusa, ho notato l'errore di battitura e l'ho risolto . Il problema esiste ancora, tuttavia. – Himmel

+0

solo un errore di battitura. il problema è lì. –

+0

Aggiornamento della risposta. Per ogni salto oltre le proprietà non definite –

-1

Sospetto che ciò possa avere a che fare con le complessità del ciclo foreach di Javascript, non con il costruttore di array (int). Utilizzo di un ciclo for normale:

for(var i = 0; i < arr.length; i += 1) { 
    console.log(arr[i] + " " + i); 
} 

ha prodotto il risultato desiderato.

2

Questo perché i metodi di array ES5 ignorano gli indici mancanti. Cioè, iterano loaa , ma a ogni iterazione controllano se la matrice ha una proprietà propria i.

Se si desidera che funzioni, è possibile utilizzare fill per creare gli indici. .

var arr = new Array(5).fill(); 
 
arr.forEach(function(v, i) { console.log('arr['+i+'] = ' + v); });