Qual é a maneira mais eficiente de filtrar ou mapear uma lista de nós no ES6?
Com base em minhas leituras, eu usaria uma das seguintes opções:
[...nodelist].filter
ou
Array.from(nodelist).filter
Qual desses você recomendaria? E existem maneiras melhores, por exemplo, sem envolver matrizes?
javascript
arrays
filter
ecmascript-6
nodelist
Christophe
fonte
fonte
babel
,[...coll]
simplesmente solicitaráArray.from(coll)
qualquer coisa que não seja umArray
....
sintaxe pode não ser suportada por IDEs mais antigos, emboraArray.from()
seja apenas um método regular.Respostas:
[...nodelist]
fará um array de fora de um objeto se o objeto for iterável.Array.from(nodelist)
fará uma matriz de um objeto se o objeto for iterável ou se o objeto for semelhante a uma matriz (tem.length
e props numéricos)Seus dois exemplos serão idênticos se
NodeList.prototype[Symbol.iterator]
existirem, porque ambos os casos cobrem iteráveis. Se o seu ambiente não foi configurado de formaNodeList
iterável, o primeiro exemplo falhará e o segundo terá êxito.Babel
atualmente não lida com este caso adequadamente .Portanto, se o seu
NodeList
for iterável, você realmente decide qual será o seu uso. Eu provavelmente escolheria caso a caso. Um benefício doArray.from
é que leva um segundo argumento de uma função de mapeamento, enquanto o primeiro[...iterable].map(item => item)
teria que criar um array temporário,Array.from(iterable, item => item)
não. Se você não estiver mapeando a lista, não importa.fonte
TL; DR;
Array.prototype.slice.call(nodelist).filter
O método slice () retorna uma matriz. Essa matriz retornada é uma cópia superficial da coleção (NodeList).
Portanto, funciona mais rápido do que Array.from ().Portanto, funciona tão rápido quanto Array.from ()Elementos da coleção original são copiados para a matriz retornada da seguinte maneira:
Breve explicação sobre os argumentos
Array.prototype.slice (beginIndex, endIndex)
Array.prototype.slice.call (namespace, beginIndex, endIndex)
fonte
Array.from
que não. É hora de encontrar uma máquina IE. Agora estou realmente confuso porque consegui usar Array.from no IE10 e no IE11: \. Este método funciona no IE10 + 11, mas Array.from não me deixa funcionar quando toda a documentação diz o contrário.Array.from
não funciona para mim no IE11 O objeto não suporta propriedade ou método 'de'Array.from
também retorna uma cópia superficial. Portanto, não vejo como você conclui que funciona mais rápido do queArray#slice
.Encontrei uma referência que usa
map
diretamente na NodeList porArray.prototype.map.call(nodelist, fn)
Não testei, mas parece plausível que seja mais rápido porque deve acessar o NodeList diretamente.
fonte
Que tal agora:
// Be evil. Extend the prototype. if (window.NodeList && !NodeList.prototype.filter) { NodeList.prototype.filter = Array.prototype.filter; } // Use it like you'd expect: const noClasses = document .querySelectorAll('div') .filter(div => div.classList.length === 0)
É a mesma abordagem mencionada nos documentos MDN para NodeList.forEach (em 'Polyfill'), funciona para IE11 , Edge, Chrome e FF.
fonte