Existe uma maneira mais eficiente de converter uma HTMLCollection em uma matriz, além de iterar pelo conteúdo da coleção e empurrar manualmente cada item em uma matriz?
javascript
arrays
object
Tom
fonte
fonte
for (var a=[], i=collection.length; i;) a[--i] = collection[i];
não muito de um "con" há :-)Array.prototype.slice.call
e o Brave (baseado no Chrome 59.0.3071) praticamente não tem diferença entre os dois testes de javascript em várias execuções. Veja jsperf.com/htmlcollection-array-vs-jquery-childrenRespostas:
terá o mesmo efeito usando o código "nativo".
Editar
Como isso gera muitas visualizações, observe (por comentário de @ oriol) que a seguinte expressão mais concisa é efetivamente equivalente:
Mas observe pelo comentário do @ JussiR, que, diferentemente da forma "detalhada", ele cria uma instância de matriz vazia, não utilizada e de fato inutilizável no processo. O que os compiladores fazem sobre isso está fora do alcance do programador.
Editar
Desde o ECMAScript 2015 (ES 6), também existe o Array.from :
Editar
O ECMAScript 2015 também fornece o operador de spread , que é funcionalmente equivalente a
Array.from
(embora observe queArray.from
suporta uma função de mapeamento como o segundo argumento).Confirmei que ambos os trabalhos acima funcionam
NodeList
.Uma comparação de desempenho para os métodos mencionados: http://jsben.ch/h2IFA
fonte
[].slice.call(htmlCollection)
também funciona.Array.from
, ou sejafrom
, não é suportado pelo IE11.não tenho certeza se essa é a mais eficiente, mas uma sintaxe concisa do ES6 pode ser:
Edit: Outro, do comentário Chris_F:
fonte
Array.from()
Array.from
, ou sejafrom
, não é suportado pelo IE11.Eu vi um método mais conciso de obter
Array.prototype
métodos em geral que também funciona. A conversão de umHTMLCollection
objeto em umArray
objeto é demonstrada abaixo:E, como mencionado nos comentários, para navegadores antigos como o IE7 e versões anteriores, basta usar uma função de compatibilidade, como:
Sei que essa é uma pergunta antiga, mas achei que a resposta aceita era um pouco incompleta; então pensei em lançar isso lá fora, FWIW.
fonte
Para uma implementação entre navegadores, sugiro que você analise a função prototype.js
$A
copiado de 1.6.1 :
Provavelmente não é usado
Array.prototype.slice
porque não está disponível em todos os navegadores. Receio que o desempenho seja muito ruim, pois há um retorno de javascript sobre oiterable
.fonte
$A
função faz na maioria das vezes.Esta é a minha solução pessoal, com base nas informações aqui (este tópico):
Onde $ A foi descrito por Gareth Davis em seu post:
Se o navegador suportar da melhor maneira, ok, caso contrário, usará o navegador cruzado.
fonte
[,,]
torna-se[undefined, undefined]
.Isso funciona em todos os navegadores, incluindo versões anteriores do IE.
Como o jsperf ainda está inativo no momento, aqui está um jsfiddle que compara o desempenho de diferentes métodos. https://jsfiddle.net/qw9qf48j/
fonte
var args = (htmlCollection.length === 1 ? [htmlCollection[0]] : Array.apply(null, htmlCollection));
Para converter de matriz para matriz de maneira eficiente, podemos usar o jQuery
makeArray
:Uso:
Um pouco mais:
Se você não deseja manter a referência ao objeto da matriz (na maioria das vezes, as HTMLCollections são alteradas dinamicamente, portanto é melhor copiá-las para outra matriz. Este exemplo presta muita atenção ao desempenho:
O que é semelhante a um array?
HTMLCollection é um
"array-like"
objeto, os objetos do tipo matriz são semelhantes ao objeto da matriz, mas perdem grande parte de sua definição funcional:fonte