Para cada um através de um array em JavaScript?

Como posso fazer um loop através de todas as entradas de um array usando JavaScript?

Pensei que fosse algo assim.
forEach(instance in theArray)

Onde theArray está a minha matriz, mas isto parece estar incorrecto.

Author: T.J. Crowder, 2012-02-17

28 answers

TL; DR

  • Não utilize for-in a não ser que o utilize com salvaguardas ou esteja pelo menos ciente do motivo pelo qual o pode morder.
  • As suas melhores apostas são normalmente ...
    • a for-of loop (ES2015+ apenas),
    • Array#forEach (spec | MDN) (ou os seus parentes some (apenas ES5),
    • um simples laço à moda antiga for,
    • ou for-in com medida.
Mas há muito mais para explorar, ler...

JavaScript tem uma semântica poderosa para looping através de arrays e objetos do tipo array. Eu dividi a resposta em duas partes: opções para arrays genuínos, e opções para coisas que são apenas array-como, como o Objeto arguments, outros objetos iteráveis (ES2015+), coleções DOM, e assim por diante.

Vou rapidamente notar que podes usar o ES2015. opções agora , mesmo nos motores ES5, por transpilamento ES2015 para ES5. Procurar por "transpiling ES2015" / "transpiling ES6" para mais informações... Muito bem, vamos ver as nossas opções.

Para Matrizes Reais

Você tem três opções em ECMAScript 5 ("ES5"), a versão mais amplamente suportado no momento, e mais duas adicionado em ECMAScript 2015 ("ES2015", "ES6"):

  1. utilizar forEach e produtos afins (ES5+)
  2. usa um simples for laço
  3. for-in correctamente
  4. utilizar for-of (utilizar implicitamente um iterador) (ES2015+)
  5. utilizar explicitamente um iterador (ES2015+)

Detalhes:

1. Utilizar forEach e

Em qualquer vagamente-ambiente moderno (assim, não IE8) onde você tem acesso à Array recursos adicionados por ES5 (diretamente ou utilizando livros), você pode usar forEach (spec | MDN):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEach aceita uma função de callback e, opcionalmente, um valor a usar como this ao invocar essa chamada (não usada acima). O callback é chamado para cada entrada na matriz, em ordem, saltando entradas inexistentes em arrays esparsos. Embora eu só tenha usado um argumento acima, o callback é chamado com três: o valor de cada entrada, o índice desse item, e uma referência ao array que você está iterando (no caso de sua função ainda não ter it handy).

A menos que esteja a apoiar navegadores obsoletos como o IE8 (que o NetApps mostra com uma quota de mercado de pouco mais de 4% a partir desta escrita em setembro de 2016), pode utilizar com prazer {[[30]} numa página web de uso geral sem um shim. Se você precisar de suportar navegadores obsoletos, shimming/polifilling forEach é fácil de fazer (procurar por "es5 shim" para várias opções).

forEach tem o benefício que você não tem que declarar variáveis de indexação e valor no âmbito de containing, como eles são fornecidos como argumentos para a função de iteração, e tão bem escopo para apenas essa iteração.

Se você está preocupado com o custo de execução de fazer uma chamada de função para cada entrada de array, não seja; detalhes.

Além disso, forEach é a função "loop through them all" , mas o ES5 definiu várias outras funções úteis "trabalhar o seu caminho através do array e fazer coisas", incluindo:

  • every (pára de rodar da primeira vez o callback devolve false ou algo do género falsey)
  • some (pára de repetir a primeira vez que o callback retorna true ou algo truthy)
  • filter (cria uma nova lista, incluindo os elementos onde a função do filtro devolve true e omite os que devolve false)
  • map (cria uma nova lista a partir dos valores devolvidos pelo callback)
  • reduce (constrói um valor repetidamente chamando o callback, passando em valores anteriores; veja a especificação para os detalhes; útil para somar o conteúdo de uma matriz e muitas outras coisas)
  • reduceRight (como reduce, mas funciona em ordem descendente em vez de ascendente)

2. Usar um simples for loop

Às vezes, os velhos costumes são os melhores.
var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
    console.log(a[index]);
}

Se o comprimento do array não mudar durante o loop, e está em código sensível ao desempenho( improvável), um pouco mais uma versão complicada a agarrar o comprimento à frente pode ser um minúsculo um pouco mais rápido:

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}

E / ou contagem regressiva:

var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}
Mas com motores JavaScript modernos, é raro ter de tirar aquele último pedaço de sumo.

Em ES2015 ou mais, você pode tornar as suas variáveis de índice e valor locais para o laço for:

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//console.log(index); // Would cause "ReferenceError: index is not defined"
//console.log(value); // Would cause "ReferenceError: value is not defined"
E quando você faz isso, não só value mas também index é recriado para cada iteração de laço, o que significa os encerramentos criados no corpo do laço mantêm uma referência ao index (e value) criado para essa iteração específica:
let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        alert("Index is: " + index);
    });
}

Se tivesses cinco divs, terias "índice é: 0" se clicasses no primeiro e "índice é: 4" se clicasses no último. Isto não funcionase usar var em vez de let.

3. Utilização for-in correctamente

As pessoas dizem-te para usares for-in, mas não é para isso que for-in serve. Loops através das propriedades enumeráveis de um objeto , não os índices de uma matriz. a ordem não está garantida, nem mesmo nos ES2015 (ES6). ES2015 definir uma ordem para propriedades de objeto (via [[OwnPropertyKeys]], [[Enumerate]], e as coisas que usá-los como Object.getOwnPropertyKeys), mas não definir que for-in vai seguir essa ordem. (Pormenores em esta outra resposta .)

Ainda assim, pode ser útil, particularmente para esparse arrays , se utilizar as salvaguardas adequadas:
// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

Note os dois controlos:

  1. Que o objecto tem a sua propriedade própria por esse nome (não uma que herde do seu protótipo), e

  2. Que a chave é uma cadeia numérica base-10 em sua forma de cadeia normal e seu valor é no caderno de especificações . Outros números (não inteiros, números negativos, números superiores a 2^32-2) não são índices de matriz. A razão é 2^32 - 2 é que isso faz com que o maior valor de índice um menor do que 2^32 - 1, que é o valor máximo que um array length pode ter. (Por exemplo, o comprimento de uma matriz encaixa em um número inteiro sem sinal de 32 bits.(Props to RobG for pointing out in a comment on my blog post that my previous test was not quite direito.)

Isso é um pequeno pedaço de adicional por iteração de loop na maioria das matrizes, mas se você tem um array esparse , ele pode ser uma maneira mais eficiente de loop porque ele só loops para entradas que realmente existem. Por exemplo, para o array acima, nós fazemos um loop de um total de três vezes (para chaves "0", "10", e lembrem-se, são cordas, não 10.001 vezes.

Agora, não vais querer escrever isso todas as vezes, por isso podes pôr isto no teu ... toolkit:
function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}
E depois usávamos assim:
for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}
Ou se você está interessado em apenas um teste "bom o suficiente para a maioria dos casos", você poderia usar isso, mas enquanto está perto, não é completamente correto:
for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

4. Use for-of (utilizar implicitamente um iterador) (ES2015+)

ES2015 adiciona iteradores ao JavaScript. A maneira mais fácil de usar iteradores é a nova declaração for-of. Parece que isto:

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

Resultado:

a
b
c
Debaixo das capas, fica um iterador do array e passa por ele, obtendo os valores a partir dele. Isto não tem o problema que o uso de for-in tem, porque ele usa um iterador definido pelo objeto (o array), e arrays definem que seus iteradores iterate através de suas entradas (Não suas propriedades). Ao contrário de for-in em ES5, a ordem em que as entradas são visitadas é a ordem numérica das suas Index.

5. Utilizar explicitamente um iterador (ES2015+)

Às vezes, é melhor usar um iterador explicitamente. Você também pode fazer isso, embora seja muito mais complicado do que for-of. Parece isto:

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

O iterador é um objecto que corresponde à definição do iterador na especificação. O seu método next devolve um novo objectode resultado de cada vez que lhe chamas. O objeto do resultado tem uma propriedade, done, dizendo-nos se está feito, e um propriedade value com o valor para essa iteração. (done é opcional se for false, value é opcional se for undefined.)

O Significado de value varia de acordo com o iterador; as matrizes suportam (pelo menos) três funções que devolvem iteradores:

  • Este é o que usei acima. Devolve um iterador onde cada value é o item da lista para essa iteração ("a", "b", e "c" no exemplo anterior).
  • keys(): Devolve um iterador onde cada value é a chave para que a iteração (para o nosso a acima, que seria "0", então "1", então "2").
  • entries(): Devolve um iterador onde cada value é um array na forma [key, value] para essa iteração.

Para Objectos De Matriz

Além de matrizes verdadeiras, existem também array-like objectos que têm uma length propriedade e propriedades com nomes numéricos: NodeList instâncias, o objecto arguments, etc. Como vamos vasculhar o conteúdo deles?

Utilize qualquer uma das opções acima para arrays

Pelo menos alguns, e possivelmente a maioria ou até mesmo todos, das aproximações do array acima frequentemente se aplicam igualmente bem aos objetos do tipo array:

  1. Uso forEach e afins (ES5+)

    As várias funções em Array.prototype são "intencionalmente genéricas" e podem normalmente ser usadas em objectos de matriz via Function#call ou Function#apply. (Ver a secção 4. 4). ressalva para objetos fornecidos pelo hospedeiro no final desta resposta, mas é um problema raro.)

    Suponha que queria usar forEach numa propriedade Node'S childNodes. Tu farias isto.

    Array.prototype.forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    

    Se você vai fazer isso muito, você pode querer pegar uma cópia da referência da função em uma variável para reutilização, por exemplo:

    // (This is all presumably in some scoping function)
    var forEach = Array.prototype.forEach;
    
    // Then later...
    forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    
  2. Usar um simples laço for

    Obviamente, um simples laço for aplica-se ao array-like objecto.

  3. Utilização for-in correctamente

    for-in com as mesmas salvaguardas que com um array deve trabalhar com objetos do tipo array também; a advertência para os objetos fornecidos pelo host em #1 acima pode ser aplicada.

  4. Use for-of (utilizar implicitamente um iterador) (ES2015+)

    for-of usará o iterador fornecido pelo objeto (se existir); teremos que ver como isso joga com os vários objetos array-like, especialmente as que recebem hospedeiros. Por exemplo, a especificação para o NodeList de querySelectorAll foi atualizada para suportar a iteração. A especificação para o HTMLCollection de getElementsByTagName não era.

  5. Utilizar explicitamente um iterador (ES2015+)

    4, Temos de ver como os iteradores funcionam.
Criar um verdadeiro array

Outras vezes, você pode querer converter um objeto array em um array verdadeiro. Fazer isso é surpreendentemente fácil:

  1. Use o slice método das matrizes

    Nós podemos usar o método slice de matrizes, que como os outros métodos mencionados acima é "intencionalmente genérico" e assim pode ser usado com objetos do tipo matriz, como este:

    var trueArray = Array.prototype.slice.call(arrayLikeObject);
    
    Então, por exemplo, se quisermos converter um NodeList em uma matriz verdadeira, podemos fazer isso:
    var divs = Array.prototype.slice.call(document.querySelectorAll("div"));
    

    Ver a Caveat para os objectos fornecidos pela máquina abaixo. Em especial, nota que isto vai falhar no IE8 e antes, que não te deixam usar objectos fornecidos pelo host como this assim.

  2. Usar espalhar a sintaxe (...)

    Também é possível usar a sintaxe de spread do ES2015 com motores JavaScript que suportam esta funcionalidade:

    var trueArray = [...iterableObject];
    

    Então, por exemplo, se quisermos converter um NodeList em uma matriz verdadeira, com a sintaxe de spread isto torna-se bastante sucinto:

    var divs = [...document.querySelectorAll("div")];
    
  3. Utilização Array.from (spec) | (MDN)

    Array.from (ES2015+, mas facilmente polifilada) cria um array a partir de um objeto array-like, opcionalmente passando as entradas através de uma função de mapeamento primeiro. Então:

    var divs = Array.from(document.querySelectorAll("div"));
    

    Ou se quisesse obter uma lista dos nomes das marcas dos elementos com uma dada classe, usaria a função de mapeamento:

    // Arrow function (ES2015):
    var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);
    
    // Standard function (since `Array.from` can be shimmed):
    var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
        return element.tagName;
    });
    
Caveat for host-provided objectos

Se você usar as funções Array.prototype com host-provided array-like objects (DOM lists and other things provided by the browser rather than the JavaScript engine), você precisa ter a certeza de testar nos seus ambientes de destino para se certificar de que o objecto fornecido pela máquina se comporta correctamente. A maioria comporta-se bem, mas é importante testar. A razão é que a maioria dos métodos Array.prototype que você provavelmente quer usar dependem do objeto fornecido pelo host dando um resposta honesta ao resumo [[HasProperty]] operação. A partir desta escrita, navegadores fazem um trabalho muito bom nisso, mas a spec 5.1 permitiu a possibilidade de um objeto hospedeiro fornecido pode não ser honesto. Está dentro §8.6.2, vários parágrafos abaixo da grande tabela perto do início dessa seção), onde diz:

Os objectos hospedeiros podem implementar estes métodos internos de qualquer forma, salvo indicação em contrário; por exemplo, uma possibilidade é que [[Get]] e [[Put]] para um objecto de máquina em particular, obtém e armazena os valores da propriedade, mas [[HasProperty]] gera sempre falso .

Não encontrei a verbia equivalente na especificação ES2015, mas ainda deve ser o caso.) Mais uma vez, a partir desta escrita os objetos comuns array-provided array-like em navegadores modernos [NodeList instâncias, por exemplo] do lidar [[HasProperty]]} corretamente, mas é importante testar.)
 6107
Author: T.J. Crowder, 2018-07-16 13:23:53

Edit : esta resposta está irremediavelmente desactualizada. Para uma abordagem mais moderna, olhe para Os métodos disponíveis em um array . Os métodos de interesse podem ser:

  • forEach
  • mapa
  • filtro
  • zip
  • reduzir
  • cada
  • alguns

A forma padrão de iterar um array em JavaScript é uma baunilha for - loop:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

Note, No entanto, que esta abordagem só é boa se ter uma matriz densa, e cada índice é ocupado por um elemento. Se a matriz é escassa, então você pode encontrar problemas de desempenho com esta abordagem, uma vez que você vai iterar sobre um monte de índices que não realmente existem na matriz. Neste caso, um laço pode ser uma ideia melhor. No entanto , você deve usar as salvaguardas apropriadas para garantir que apenas as propriedades desejadas do array (ou seja, os elementos array) são aceitos, uma vez que o for..in-loop também será enumerado nos navegadores antigos, ou se as propriedades adicionais forem definidas como enumerable.

Em ECMAScript 5 {[10] } haverá um método forEach no protótipo do array, mas não é suportado nos navegadores legados. Então para ser capaz de usá-lo consistentemente você deve ter um ambiente que o suporta (por exemplo, nó .js for server side JavaScript), or use a "Polyfill". O Polifill para esta funcionalidade é, no entanto, trivial e uma vez que torna o código mais fácil de ler, é um bom polifill para incluir.

 455
Author: PatrikAkerstrand, 2018-10-06 06:11:45

Se estiver a utilizar o jQuery biblioteca, você pode usar jQuery.cada:

$.each(yourArray, function(index, value) {
  // do your stuff here
});

Editar :

Por pergunta, O Utilizador quer o código em javascript em vez de jQuery, por isso a edição é

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}
 207
Author: Poonam, 2015-11-12 05:17:40

Volta para trás

Acho que o reverso do laço merece uma menção aqui:
for (var i = array.length; i--; ) {
     // process array[i]
}
Vantagens:
  • não é necessário declarar uma variável temporária len, nem comparar com array.length em cada iteração, uma das quais poderá ser uma optimização de minutos.
  • remover irmãos do DOM em ordem inversa é normalmente mais eficiente. (O navegador precisa fazer menos deslocamento de elementos em seu interior matriz.)
  • Se modificar a matriz while loop, durante ou após a index i (por exemplo, remover ou inserir um item em array[i]), então um ciclo para a frente iria ignorar o item que deslocado para a esquerda para a posição i, ou re-process ith item que foi deslocado para a direita. Em um tradicional laço, você poderia atualizar I para apontar para o próximo item que precisa de processamento-1, mas simplesmente reverter a direção da iteração é muitas vezes um solução mais simples e solução mais elegante.
  • da mesma forma, ao modificar ou remover os elementos DOM aninhados, o processamento em reverso pode contornar erros. Por exemplo, considere modificar o innerHTML de um nó pai antes de lidar com seus filhos. No momento em que o nó-criança é alcançado, ele será separado do DOM, tendo sido substituído por uma criança recém-criada quando o innerHTML do pai foi escrito.
  • é mais curto para digitar, e leia , do que algumas das outras opções disponíveis. Apesar de perder para forEach() e para os ES6's.

Desvantagens:

  • processa os itens em ordem inversa. Se você estava construindo uma nova matriz a partir dos resultados, ou imprimindo coisas na tela, naturalmente a saída será revertida em relação à ordem original.
  • inserir repetidamente irmãos no DOM como um primeiro filho, a fim de manter a sua ordem é menos eficiente. (O navegador teria que mudar as coisas corretamente.) Para criar nós DOM de forma eficiente e em ordem, basta fazer um loop para a frente e adicionar como normal (e também usar um "fragmento de Documento").
  • o ciclo inverso é confuso para os programadores Júnior. (Você pode considerar que uma vantagem, dependendo de sua perspectiva.)

Devo usá-lo sempre?

Alguns programadores usam o inverso para o loop por omissão , a menos que haja uma boa razão para seguir em frente.

Embora os ganhos de desempenho sejam normalmente insignificantes, parece que grita:
"Faz isto a todos os itens da lista, não quero saber da ordem!"

No Entanto, na prática, que é não, na verdade, uma indicação confiável de intenções, uma vez que ele é indistinguível de uma dessas ocasiões, quando você fazer cuidados sobre a ordem, e realmente fazer necessidade para loop no sentido inverso. Por isso, na verdade ... outra construção seria necessária para expressar com precisão a intenção de "don't care", algo atualmente indisponível na maioria das línguas, incluindo ECMAScript, mas que poderia ser chamado, por exemplo, forEachUnordered().

Se a ordem não importa, e a eficiência é uma preocupação (no laço mais interior de um jogo ou motor de animação), então pode ser aceitável usar o inverso para o laço como o seu padrão go-to. Basta lembrar que ver um reverso para o loop no código existente Não necessariamente significa que a ordem é irrelevante!

É melhor usar forEach ()

Em geral, para um código de nível superior onde clareza e segurança são preocupações maiores, eu recomendaria usar Array::forEach como o seu padrão por omissão:

    É claro ler.
  • indica que I não vai ser deslocado dentro do bloco (o que é sempre uma possível surpresa escondida em longas for e while loops.)
  • Dá você é uma escopo livre para fechamentos. Reduz a fuga de variáveis locais e a colisão acidental com (e mutação) variáveis externas.

Então quando você vê o reverso para o loop em seu código, isso é uma dica de que ele é revertido por uma boa razão (talvez uma das razões descritas acima). E ver um avanço tradicional para o loop pode indicar que a mudança pode acontecer.

(Se a discussão de intenções não faz sentido para ti, Então tu e o teu código podem beneficie de assistir à palestra de Crockford sobre o estilo de programação e o seu cérebro.)


Como funciona?
for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

Você vai notar que i-- é a cláusula do meio (onde geralmente vemos uma comparação) e a última cláusula está vazia (onde normalmente vemos i++). Isso significa que i-- também é usado como condiçãopara continuação. Crucialmente, é executado e verificado antes de cada iteração.

  • Como pode? começar em array.length sem explodir?

    Porque i-- executa antes de cada iteração, na primeira iteração, nós vamos estar acessando o item em array.length - 1 o que evita quaisquer questões com Matriz-out-of-bounds undefined itens.

  • Porque não pára de iterar antes do índice 0?

    O laço vai parar de iterar quando a condição i-- se avalia a um valor de falsey (quando produz 0).

    O truque é que ao contrário --i, os decrementos do operador i-- mas produz o valor antes o Decreto. A sua consola pode demonstrar isto:

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    Assim, na última iteração, I foi anteriormente 1 e a expressão muda-a para 0 mas na verdade rende 1 (e assim a condição passa. Na próxima iteração i-- as alterações I a -1 mas rende 0 (falsey), fazendo com que a execução caia imediatamente do fundo do laço. ([34]} nos atacantes tradicionais para o laço, i++ e ++i são intercambiáveis (como Douglas Crockford aponta). No entanto, no reverso para o loop, porque o nosso decrement é também a nossa expressão de condição, nós devemos ficar com i-- Se queremos processar o item no índice 0.

Trivialidade

Algumas pessoas gostam de desenhar uma pequena seta no reverso., e termina com um piscar de olhos.
for (var i = array.length; i --> 0 ;) {

os créditos vão para WYL por me mostrar os benefícios e horrores do reverso do loop.

 88
Author: joeytwiddle, 2017-05-23 12:03:09

Algumas linguagens do estilo usamforeach para fazer loop através de enumerações. Em JavaScript isto é feito com o for..in estrutura do ciclo:

var index,
    value;
for (index in obj) {
    value = obj[index];
}
Há um senão. for..in irá percorrer cada um dos membros enumeráveis do objecto, e os membros no seu protótipo. Para evitar ler valores que são herdados através do protótipo do objeto, basta verificar se a propriedade pertence ao objeto:
for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

Adicionalmente, ECMAScript 5 {[14] } adicionou um forEach método para Array.prototype que pode ser usado para enumerar sobre uma matriz usando um recuo (o polifill está nos documentos, de modo que você ainda pode usá-lo para navegadores mais antigos):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

É importante notar que Array.prototype.forEach não se quebra quando o callback retorna false. jQuery e sublinhado.js fornecem as suas próprias variações em each para fornecer laços que podem ser de curto-circuito.

 72
Author: zzzzBov, 2013-07-13 01:18:21

Se quiser fazer um loop sobre uma matriz, use o loop normal de três partes for.

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

Pode-se obter algumas optimizações de desempenho Cache myArray.length ou iterando-se ao contrário.

 31
Author: Quentin, 2012-02-17 13:55:46

A forEach implementation (see in jsFiddle):

function forEach(list,callback) {
  var length = list.length;
  for (var n = 0; n < length; n++) {
    callback.call(list[n]);
  }
}

var myArray = ['hello','world'];

forEach(
  myArray,
  function(){
    alert(this); // do something
  }
);
 25
Author: nmoliveira, 2013-12-18 12:22:55

Se não se importar de esvaziar a matriz:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

x irá conter o último valor de y e será removido do array. Você também pode usar shift() que dará e removerá o primeiro item de y.

 25
Author: gaby de wilde, 2014-05-30 18:37:32

Eu sei que este é um post antigo, e já há tantas grandes respostas. Para um pouco mais de Completude, pensei em juntar outro usando AngularJS. Claro, isso só se aplica se você estiver usando Angular, obviamente, no entanto, eu gostaria de colocá-lo de qualquer maneira.

angular.forEach leva 2 argumentos e um terceiro argumento opcional. O primeiro argumento é o objeto (array) para iterar, o segundo argumento é a função iterator, e o terceiro argumento opcional é o contexto do objeto (basicamente referido dentro do laço como 'isto'.

Existem diferentes maneiras de usar o laço forEach do angular. O mais simples e provavelmente mais usado é

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

Outra maneira que é útil para copiar itens de uma matriz para outra é

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

No entanto, você não tem que fazer isso, você pode simplesmente fazer o seguinte e é equivalente ao exemplo anterior:

angular.forEach(temp, function(item) {
    temp2.push(item);
});

Agora há prós e contras de usar a função angular.forEach em oposição ao construído com sabor a baunilha.

Prós

  • facilidade de leitura
  • facilidade de contração
  • Se disponível, {[4] } usará o circuito ES5 forEach. Agora, eu vou chegar a eficiência na seção cons, como os loops forEach são muito mais lentos do que os loops for. Menciono isto como profissional porque é bom ser consistente e padronizado.

Considere os seguintes 2 laços aninhados, que fazem exatamente a mesma coisa. Digamos que que temos 2 matrizes de objetos e cada objeto contém uma matriz de resultados, cada um dos quais tem uma propriedade de valor que é uma string (ou seja o que for). E digamos que precisamos de iterar cada um dos resultados e, se forem iguais, então executem alguma acção.

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

Admito que este é um exemplo hipotético muito simples, mas eu escrevi o triplo embutido para loops usando a segunda abordagem e foi Muito difícil de ler, e escrever para isso questao.

Cons

    Eficiência. angular.forEach, e o nativo forEach, por falar nisso, são ambos Muito mais lentos do que o laço normal for....cerca de 90% mais lento . Assim, para grandes conjuntos de dados, o melhor é manter o laço nativo for. Sem Pausa, Continuar ou devolver o suporte. continue é realmente suportado por " acidente ", para continuar em um {[[4] } Você simples colocar uma declaração return; na função como angular.forEach(array, function(item) { if (someConditionIsTrue) return; }); o que fará com que a continue fora da função para essa iteração. Isto também se deve ao fato de que o nativo forEach não suporta quebrar ou continuar.
Tenho a certeza de que também há outros prós e contras, e por favor, estejam à vontade para adicionar os que acharem mais adequados. Eu acho que, resumindo, se você precisa de eficiência, fique apenas com o loop nativo para suas necessidades de looping. Mas, se os seus conjuntos de dados são mais pequenos e uma certa eficiência é aceitável desistir em troca de legibilidade e writitability, então, por todos os meios, atira-o para dentro daquele menino mau.
 25
Author: user2359695, 2014-06-20 22:56:52

Uma solução fácil agora seria usar o sublinhado de .js library. Ele está fornecendo muitas ferramentas úteis, como each e irá automaticamente delegar o trabalho para o nativo forEach se disponível.

Um exemplo do CodePen de como funciona é:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

Ver também

 24
Author: Micka, 2015-05-30 22:23:09

Provavelmente o laço for(i = 0; i < array.length; i++) não é a melhor escolha. Por quê? Se tiver isto:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

O método vai ligar de array[0] para array[2]. Primeiro, isso irá primeiro variáveis de referência que você nem tem, segundo você não teria as variáveis na matriz, e terceiro isso vai tornar o código mais ousado. Olha, é o que eu uso.

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

E se queres que seja uma função, podes fazer isto:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

Se quiseres partir, um pouco mais lógica:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

Exemplo:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

Devolve:

//Hello
//World
//!!!
 21
Author: Federico Piragua, 2014-03-08 10:49:27

Existem três implementações de foreach em jQuery como se segue.

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3
 21
Author: Rajesh Paul, 2014-03-08 10:50:06

A partir do ES6:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

Onde of evita as esquisitices associadas a in e faz com que funcione como o laço for de qualquer outra linguagem, e let liga-se i dentro do laço em oposição a dentro da função.

Os suspensórios ({}) podem ser omitidos quando existe apenas um comando (por exemplo, no exemplo acima).

 19
Author: Zaz, 2016-10-20 15:21:43

Não há nenhum laço for each em nativoJavaScript . Você pode usar bibliotecas para obter esta funcionalidade (eu recomendo sublinhado.js ), use um simples for em laço.

for (var instance in objects) {
   ...
}

No entanto, note que pode haver razões para usar um loop ainda mais simples for (ver a questão de fluxo de pilha por que está usando "for...in" com a iteração da matriz é assim tão má ideia?)

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}
 15
Author: joidegn, 2017-05-23 11:47:36

Este é um iterador para uma lista não-esparsa onde o índice começa em 0, que é o cenário típico ao lidar com o documento.getElementsByTagName ou document.querySelectorAll)

function each( fn, data ) {

    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');

    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   

    return this;
}

Array.prototype.each = each;  

Exemplos de Utilização:

Exemplo #1

var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]

Exemplo #2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

Cada etiqueta p recebe class="blue"

Exemplo #3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

Todas as outras etiquetas p recebem class="red">

Exemplo #4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);
E finalmente ... as primeiras 20 etiquetas p azuis são alteradas para verde

Cuidado ao usar string como função: a função é criada fora de contexto e deve ser usada apenas onde você tem certeza de escopo variável. Caso contrário, é melhor passar funções onde escopo é mais intuitivo.

 15
Author: Tim, 2016-09-29 12:28:20

Existem algumas maneiras de percorrer um array em JavaScript, como abaixo:

- é a mais comum. Bloco completo de código para looping

var languages = ["JAVA", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

Enquanto - loop enquanto uma condição está terminada. Parece ser o loop mais rápido

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

Do / while - também loop através de um bloco de código, enquanto o a condição é verdadeira, vai correr pelo menos uma vez

var text = ""
var i = 0;
do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>

Laços funcionais - forEach, map, filter, também reduce (Eles fazem loop através da função, mas usado se você precisa fazer algo com o seu array, etc.

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>
Para mais informações e exemplos sobre programação funcional em arrays, veja o post do blogProgramação Funcional em JavaScript: mapear, filtrar e reduzir.
 14
Author: Alireza, 2017-11-27 12:29:50
Não há capacidade interior para entrar. Para interromper a execução use o Array#some como em baixo:
[1,2,3].some(function(number) {
    return number === 1;
});

Isto funciona porque some devolve verdadeiro assim que qualquer um dos callbacks, executado por ordem de matriz, devolve verdadeiro, fazendo curto-circuito na execução do resto. Resposta Original ver Array prototype for some

 12
Author: Priyanshu Chauhan, 2017-05-23 12:34:59

ECMAScript5 (a versão em Javascript) para trabalhar com Arrays.

ForEach - itera através de cada item da matriz e faz o que for preciso com cada item.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is the #" + (index+1) + " in musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

No caso de, estar mais interessado na operação em array usando alguma funcionalidade incorporada.

Map - cria um novo array com o resultado da função de callback. Este método é bom para ser usado quando você precisa formatar os elementos de seu array.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

Reduzir o nome diz que reduz o array a um único valor, chamando a função dada passando no elemento currentct e o resultado da execução anterior.

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

Cada - Devolve verdadeiro ou falso se todos os elementos da matriz passarem no teste na função de callback.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];  
ages.every(function(elem) {  
  return elem >= 18;
});

// Output: false

Filtro - muito semelhante a todos, excepto que o filtro devolve um array com os elementos que retornam verdadeiros à função indicada.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]
Espero que isto seja útil.
 12
Author: Anil Kumar Arya, 2017-06-30 17:36:57
{[[2]} eu também gostaria de adicionar isto como uma composição de um laço reverso e uma resposta acima para alguém que gostaria desta sintaxe também.
var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

Prós:

{[[2]} o benefício para isto: você já tem a referência no primeiro como isso não precisa ser declarado mais tarde com outra linha. É útil quando se faz looping através do conjunto de objetos.

Cons:

Isto irá quebrar sempre que a referência for falsa - falsey (indefinida, etc.). Pode ser utilizado como mas é uma vantagem. No entanto, seria um pouco mais difícil de ler. E também dependendo do navegador pode ser" não " otimizado para trabalhar mais rápido do que o original.

 9
Author: Volkan Seçkin Akbayır, 2017-11-19 16:27:44

JQuery way using $.map:

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];
 8
Author: DanFromGermany, 2014-04-01 11:15:26

Uma maneira mais próxima da sua ideia seria usar {[[2]} que aceita uma função de clojure que será executada para cada elemento da matriz.

myArray.forEach(
  (item) => {
    // do something 
    console.log(item);
  }
);

Outra forma viável seria usar {[3] } que funciona da mesma forma, mas também mutates cada elemento e devolve-o como:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]
 4
Author: Ante Jablan Adamović, 2017-11-09 15:31:44

A sintaxe lambda normalmente não funciona em IE 10 ou em baixo.

Normalmente uso o

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});


If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters

$("#ul>li").each(function(**index,value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});
 3
Author: Murtuza Husain, 2018-08-16 08:09:53
var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})
 1
Author: John, 2018-03-15 22:48:33
Podes chamar o forEach assim:
let Array = [1,3,2];

theArray.forEach((element)=>{ 
  // use the element of the array
  console.log(element) 
}

O elemento terá o valor de cada índice de 0 ao comprimento da matriz.

Resultado:

1    
3    
2

Explicação:

O ForEach está na classe protótipo. você também pode chamar isso de theArray.prototipo.forEach(...);

Protótipo: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

Você também pode alterar sobre uma matriz como esta:

for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}
 1
Author: Nouman Dilshad, 2018-07-17 12:30:51

Se quiser usar forEach(), vai parecer - se com -

theArray.forEach ( element => { console.log(element); });

Se quiser usar for(), vai parecer -

for(let idx = 0; idx < theArray.length; idx++){ let element = theArray[idx]; console.log(element); }

 0
Author: Harunur Rashid, 2018-05-30 09:05:30

Se tem uma grande variedade deve usar iterators para ganhar alguma eficiência. Iteradores são uma propriedade de certos JavaScript coleções (como Map, Set, String, Array). Mesmo, for..of utilizações iterator debaixo do capô.

Os iteradores melhoram a eficiência ao permitir que você consuma os itens de uma lista um de cada vez como se fossem um fluxo. O que faz um iterator especial é como ele atravessa uma colecção. Outros loops precisam carregar toda a coleção na frente, a fim de iterar sobre ele, enquanto que um iterador só precisa saber a posição atual na coleção. Acede ao item actual chamando o método iterador. O próximo método irá devolver o value da rubrica actual e de a boolean indicar quando chegou ao fim da colecção. O seguinte é um exemplo de criação de um iterador de matriz.

Transforme a sua matriz regular em iterador usando values() método como este:

    const myArr = [2,3,4]

let it = myArr.values();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Você também pode transformar o seu array regular para iterador usando Symbol.iterator assim:

const myArr = [2,3,4]

let it = myArr[Symbol.iterator]();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Também pode transformar o seu Normal {[15] } num iterator Assim.:

let myArr = [8, 10, 12];

function makeIterator(array) {
    var nextIndex = 0;
    
    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
};

var it = makeIterator(myArr);

console.log(it.next().value);   // {value: 8, done: false}
console.log(it.next().value);   // {value: 10, done: false}
console.log(it.next().value);   // {value: 12, done: false}
console.log(it.next().value);   // {value: undefined, done: true}

Nota:

    Os iteradores são de natureza exaustiva.
  • os objectos não são iterable por omissão. Utilização for..in nesse caso, porque em vez de valores funciona com chaves.
Pode ler mais sobre:iteration protocol toma.
 0
Author: BlackBeard, 2018-07-06 11:32:03

Resumo:

[[40]] quando iterando sobre uma matriz, muitas vezes podemos querer alcançar um dos seguintes objetivos:
  1. Queremos entrar no array e criar um novo array.

    Array.prototype.map

  2. Queremos entrar no array e não criar um novo array.

    Array.prototype.forEach

    for..of ciclo

Em JS há muitas maneiras de alcançar ambos os objetivos. No entanto, alguns são mais conventivo do que outros. Abaixo você pode encontrar alguns métodos comumente usados (o imo mais conventivo) para realizar iteração de array em javascript.

A criar uma nova matriz: Map

map() é uma função localizada em Array.prototype que pode transformar todos os elementos de um array e depois devolve um array novo. map() toma como argumento uma função de callback e funciona da seguinte maneira:

let arr = [1, 2, 3, 4, 5];

let newArr = arr.map((element, index, array) => {
  return element * 2;
})

console.log(arr);
console.log(newArr);
O callback que temos passou para map() como um argumento é executado para cada elemento. Em seguida, um array é devolvido que tem o mesmo comprimento que o array original. Neste novo elemento array é transformado pela função callback passada como um argumento para map().

A diferença distinta entre map e outros loop mecanismo como forEach e for..of loop que são map retorna como nova matriz e deixa a velha matriz intacta (exceto se explicitamente manipulá-lo com o pensa como splice).

Note também que o callback da função map fornece como segundo argumento o número de índice da iteração actual. Além disso, o terceiro argumento fornece a matriz na qual map foi chamado. Às vezes estas propriedades podem ser muito úteis.

Circuito com forEach

forEach é uma função que está localizada em Array.prototype que toma uma função de callback como um argumento. Ele então executa esta função de callback para cada elemento na matriz. Em contraste com o map() função a função forEach não devolve nada (undefined). Por exemplo:

let arr = [1, 2, 3, 4, 5];

arr.forEach((element, index, array) => {

  console.log(element * 2);

  if (index === 4) {
    console.log(array)
  }
  // index, and oldArray are provided as 2nd and 3th argument by the callback

})

console.log(arr);

Assim como a função map, o callback forEach fornece como segundo argumento o número de índice da iteração actual. Também o terceiro argumento fornece a matriz na qual forEach foi chamado.

Circular através de elementos usando for..of

O laço for..of passa por todos os elementos de uma matriz (ou qualquer outro objecto iterável). Funciona em a seguinte maneira:

let arr = [1, 2, 3, 4, 5];

for(let element of arr) {
  console.log(element * 2);
}

No exemplo acima element representa um elemento array e arr é o array que queremos fazer circular. Não que o nome element seja arbitrário e poderíamos ter escolhido qualquer outro nome como 'el' ou algo mais declarativo quando isso for aplicável.

Não confunda o laço com o laço. for..in fará um loop através de todas as propriedades enumeráveis do array, enquanto que o loop for..of fará apenas um loop. circular pelos elementos do array. Por exemplo:

let arr = [1, 2, 3, 4, 5];

arr.foo = 'foo';

for(let element of arr) {
  console.log(element);
}

for(let element in arr) {
  console.log(element);
}
 0
Author: Willem van der Veen, 2018-09-08 10:11:23

function printList(callback) {
    // do your printList work
    console.log('printList is done');
    callback();
}

function updateDB(callback) {
    // do your updateDB work
    console.log('updateDB is done');
    callback()
}

function getDistanceWithLatLong(callback) {
    // do your getDistanceWithLatLong work
    console.log('getDistanceWithLatLong is done');
    callback();
}

function runSearchInOrder(callback) {
    getDistanceWithLatLong(function() {
        updateDB(function() {
            printList(callback);
        });
    });
}

runSearchInOrder(function(){console.log('finished')});

A saída é igual à saída a festa com a Lothian acabou. o updateDB está pronto a lista de impressões está pronta terminado

 -2
Author: Avinash Maurya, 2018-10-01 10:18:28