forEach no array de undefined criado pelo construtor Array

Só estou me perguntando por que não é possível fazer paraEach na matriz de indefinido.

Código:

var arr = new Array(5); // [undefined x 5] //ES5 forEach arr.forEach(function(elem, index, array) { console.log(index); }); //underscore each _.each(arr, function(elem, index, array) { console.log(index); }); 

Ambos os exemplos não executam function.

Agora para fazer foreach, eu tenho que fazer:

 var arr = [0,0,0,0,0]; 

Então faça para sempre.

Eu estou tentando fazer uma matriz com tamanho especificado e loop através dele, evitando for loop. Eu acho que é mais claro usando forEach que for loop. Com array com tamanho 5 não é um problema, mas seria feio com matrizes maiores.

Por que há um problema de loop através da matriz de valores indefinidos?

    Array(5) é essencialmente equivalente a

     var arr = []; arr.length = 5; 

    Em javascript, a alteração da duração da matriz não define nenhum valor para suas propriedades numéricas nem define essas propriedades no object da matriz. Portanto, propriedades numéricas são indefinidas em vez de ter um valor indefinido. Você pode verificar usando:

     Object.keys(arr) 

    Quando iterating javascript itera através de propriedades numéricas da matriz, portanto, se estes não existirem, não há nada para iterar.

    Você pode verificar isso fazendo:

     var arr = Array(5) //prints nothing arr.forEach(function(elem, index, array) { console.log(index); }); arr[3] = 'hey' //prints only 'hey' even though arr.length === 5 arr.forEach(function(elem, index, array) { console.log(index); }); 

    O seguinte código:

     var arr = [undefined, undefined]; 

    cria e array de length ===2 e define as propriedades numéricas 0 e 1 como indefinidas .

    Olhando para uma implementação simplificada de .forEach() pode ajudar.

     Array.prototype.my_for_each = function(callback, thisArg) { for (var i = 0; i < this.length; i++) { if (i in this) { callback.call(thisArg, this[i], i, this); } } }; 

    Assim, você pode ver que o que acontece é que o método faz a iteração de todo o Array (de acordo com a especificação) , mas só invoca o retorno de chamada se o membro realmente existir. Ele verifica procurando a propriedade (o índice) usando o operador in , que testa para ver se o object possui ou herda a propriedade.

    Se in mostra que o índice existe, o retorno de chamada é invocado.


    Então, dada esta matriz:

     var arr = ["foo", "bar", "baz"]; 

    Isso produzirá todos os 3 itens:

     arr.my_for_each(function(item) { console.log(item); }); // "foo" "bar" "baz" 

    Mas se usarmos delete para remover um membro, ele deixará um buraco no Array, que agora será ignorado.

     delete arr[1]; arr.my_for_each(function(item) { console.log(item); }); // "foo" "baz" 

    Quando você criou um Array usando Array(5) , ele criou um sem membros, mas com o .length definido como 5 . Portanto, este é um exemplo de uma Matriz esparsa (muito esparsa neste exemplo). Como nenhum dos índices será encontrado por in , o retorno de chamada nunca é invocado.