Você acha que há uma grande diferença em ... em e para loops? Que tipo de "para" você prefere usar e por quê?
Digamos que temos uma matriz de matrizes associativas:
var myArray = [{'key': 'value'}, {'key': 'value1'}];
Para que possamos iterar:
for (var i = 0; i < myArray.length; i++)
E:
for (var i in myArray)
Não vejo grande diferença. Existem problemas de desempenho?
javascript
andrii
fonte
fonte
myArray.forEach(callback[, thisarg])
.if(myArray.hasOwnProperty(i)){true}
['foo', 'bar', 'baz'].forEach(function(element, index, array){ console.log(element, index, array); });
é OK para usar praticamente em todos os lugares, exceto em IE8- e é de longe o mais elegante sintaxefor...of
declaração no ECMAScript 6 , por exemplo:for (let i of myArray) console.log(i);
Respostas:
A escolha deve basear-se em qual idioma é melhor compreendido.
Uma matriz é iterada usando:
Um objeto usado como uma matriz associativa é iterado usando:
A menos que você tenha razões que abalem a terra, siga o padrão estabelecido de uso.
fonte
for
, não avaliar a.length cada vez no loop.i < l
, nãoi < a
, na sua condição de loop for.Douglas Crockford recomenda em JavaScript: The Good Parts (página 24) para evitar o uso da
for in
declaração.Se você usar o
for in
loop sobre nomes de propriedades em um objeto, os resultados não serão ordenados. Pior: você pode obter resultados inesperados; inclui membros herdados da cadeia de protótipos e o nome dos métodos.Tudo, exceto as propriedades, pode ser filtrado com
.hasOwnProperty
. Este exemplo de código faz o que você provavelmente queria originalmente:fonte
name
variável:for(var name in object)...
caso contrário, se esse código estiver dentro de uma função, por exemplo, aname
variável acabará sendo uma propriedade do objeto global (uma atribuição a um identificador não declarado faz isso), também no novo ECMAScript 5 Modo estrito, esse código lançará aReferenceError
.FYI - Usuários do jQuery
O
each(callback)
método do jQuery usafor( ; ; )
loop por padrão e será usadofor( in )
apenas se o comprimento forundefined
.Portanto, eu diria que é seguro assumir a ordem correta ao usar esta função.
Exemplo :
A desvantagem de usar isso é que, se você estiver executando alguma lógica que não seja da interface do usuário, suas funções serão menos portáteis para outras estruturas. A
each()
função provavelmente é melhor reservada para uso com seletores jQuery efor( ; ; )
pode ser aconselhável caso contrário.fonte
existem diferenças de desempenho, dependendo do tipo de loop que você usa e em qual navegador.
Por exemplo:
é quase duas vezes mais rápido em alguns navegadores do que:
No entanto, a menos que suas matrizes sejam ENORME ou você as repita constantemente, todas são rápidas o suficiente. Eu duvido seriamente que o loop de matriz seja um gargalo no seu projeto (ou em qualquer outro projeto)
fonte
for(var i = myArray.length; i--;)
Observe que o método Array.forEach nativo agora é amplamente suportado .
fonte
Resposta atualizada para a versão atual de 2012 de todos os principais navegadores - Chrome, Firefox, IE9, Safari e Opera suportam o array.forEach nativo do ES5.
A menos que você tenha algum motivo para oferecer suporte ao IE8 nativamente (tendo em mente que o ES5-shim ou o quadro Chrome pode ser fornecido a esses usuários, o que fornecerá um ambiente JS adequado), é mais fácil usar simplesmente a sintaxe adequada do idioma:
A documentação completa do array.forEach () está no MDN.
fonte
Os dois não são os mesmos quando a matriz é escassa.
fonte
Usando o forEach para pular a cadeia de protótipos
Apenas um adendo rápido à resposta do @ nailer acima , usando forEach com Object.keys significa que você pode evitar a iteração na cadeia de protótipos sem precisar usar o hasOwnProperty.
fonte
Tenho uma segunda opinião de que você deve escolher o método de iteração de acordo com sua necessidade. Eu sugiro que você nunca faça loop nativo
Array
com afor in
estrutura. É muito mais lento e , como Chase Seibert apontou no momento atrás, não é compatível com o framework Prototype.Há uma excelente referência em diferentes estilos de loop que você absolutamente deve observar se trabalhar com JavaScript . Não faça otimizações precoces, mas você deve guardar essas coisas em algum lugar na sua cabeça.
Eu usaria
for in
para obter todas as propriedades de um objeto, o que é especialmente útil ao depurar seus scripts. Por exemplo, eu gosto de ter essa linha à mão quando eu explorar objetos desconhecidos:Ele despeja o conteúdo de todo o objeto (junto com os corpos dos métodos) no meu log do Firebug. Muito útil.
fonte
Aqui está algo que eu fiz.
é assim que você usaria,
isso funcionará em matrizes e objetos (como uma lista de elementos HTML)
Acabei de fazer isso, estou aberto a sugestões :)
fonte
Eu usaria os diferentes métodos com base em como eu queria fazer referência aos itens.
Use foreach se quiser apenas o item atual.
Use para se você precisar de um indexador para fazer comparações relativas. (Ou seja, como isso se compara ao item anterior / próximo?)
Eu nunca notei uma diferença de desempenho. Eu esperaria até ter um problema de desempenho antes de me preocupar com isso.
fonte
Com for (var i em myArray) você pode loop sobre objetos também, i irá conter o nome da chave e você pode acessar a propriedade via myArray [i] . Adicionalmente, quaisquer métodos que você terá adicionado ao objeto será incluído no circuito, também, ou seja, se você usar qualquer estrutura externa como jQuery ou protótipo, ou se você adicionar métodos para protótipos de objetos diretamente, em um ponto i irá apontar para esses métodos.
fonte
Cuidado!
Se você tiver várias tags de script e estiver pesquisando informações nos atributos da tag, por exemplo, precisará usar a propriedade .length com um loop for, porque não é uma matriz simples, mas um objeto HTMLCollection.
https://developer.mozilla.org/en/DOM/HTMLCollection
Se você usar a instrução foreach para (var i em yourList), ela retornará propriedades e métodos do HTMLCollection na maioria dos navegadores!
Mesmo se getElementsByTagName devolver um NodeList, a maioria dos navegadores retornará uma HTMLCollection: https://developer.mozilla.org/en/DOM/document.getElementsByTagName
fonte
Para loops em matrizes não é compatível com o protótipo. Se você acha que pode precisar usar essa biblioteca no futuro, faria sentido manter loops.
http://www.prototypejs.org/api/array
fonte
Eu já vi problemas com o "para cada" usando objetos e protótipo e matrizes
meu entendimento é que o para cada um é para propriedades de objetos e não matrizes
fonte
Se você realmente deseja acelerar o seu código, e quanto a isso?
é meio que ter a lógica while dentro da instrução for e é menos redundante. O firefox também possui Array.forEach e Array.filter
fonte
Um código mais curto e melhor de acordo com jsperf é
fonte
Use o loop Array (). ForEach para aproveitar o paralelismo
fonte
Array.prototype.forEach
, não executará várias chamadas para o retorno de chamada em paralelo.for (;;) é para matrizes : [20,55,33]
for..in é para Objetos : {x: 20, y: 55: z: 33}
fonte
Seja cuidadoso!!! Estou usando o Chrome 22.0 no Mac OS e estou tendo problemas com o para cada sintaxe.
Não sei se este é um problema do navegador, um problema de javascript ou algum erro no código, mas é MUITO estranho. Fora do objeto, ele funciona perfeitamente.
fonte
Há uma diferença importante entre os dois. O for-in itera sobre as propriedades de um objeto, portanto, quando o caso é uma matriz, ele não apenas itera sobre seus elementos, mas também sobre a função "remover" que possui.
Você pode usar o for-in com um
if(myArray.hasOwnProperty(i))
. Ainda assim, ao iterar sobre matrizes, eu sempre prefiro evitar isso e apenas usar a instrução for (;;).fonte
Embora os dois sejam muito parecidos, há uma pequena diferença:
neste caso, a saída é:
PADRÃO PARA LOOP:
ARRAY [0] = A
ARRAY [1] = B
ARRAY [2] = C
enquanto neste caso a saída é:
LOOP FOR-IN:
ARRAY [1] = B
ARRAY [2] = C
ARRAY [10] = D
ARRAY [ABC] = 123
fonte
A instrução for in permite fazer um loop pelos nomes de todas as propriedades de um objeto. Infelizmente, ele também percorre todos os membros que foram herdados pela cadeia de protótipos. Isso tem o efeito colateral ruim de atender às funções do método quando o interesse está nos membros dos dados.
fonte