Jaki jest najbardziej skuteczny sposób filtrowania lub mapowania listy węzłów w ES6?
W oparciu o moje odczyty użyłbym jednej z następujących opcji:
[...nodelist].filter
lub
Array.from(nodelist).filter
Który byś polecił? Czy są lepsze sposoby, na przykład bez użycia tablic?
javascript
arrays
filter
ecmascript-6
nodelist
Christophe
źródło
źródło
babel
, po[...coll]
prostu wywołaArray.from(coll)
wszystko, co nie jest plikiemArray
....
składnia może nie być obsługiwana przez starsze IDE, chociażArray.from()
jest to zwykła metoda.Odpowiedzi:
[...nodelist]
utworzy tablicę z obiektu, jeśli obiekt jest iterowalny.Array.from(nodelist)
utworzy tablicę z obiektu, jeśli obiekt jest iterowalny lub jeśli obiekt jest podobny do tablicy (ma.length
i numeryczne właściwości)Twoje dwa przykłady będą identyczne, jeśli
NodeList.prototype[Symbol.iterator]
istnieją, ponieważ oba przypadki obejmują iterowalne. Jeśli jednak środowisko nie zostało skonfigurowane w sposób umożliwiającyNodeList
iterację, pierwszy przykład zakończy się niepowodzeniem, a drugi powiedzie się.Babel
obecnie nie obsługuje prawidłowo tej sprawy .Więc jeśli twój
NodeList
jest iterowalny, to naprawdę zależy od ciebie, którego użyjesz. Prawdopodobnie wybrałbym indywidualnie dla każdego przypadku. Jedną z korzyściArray.from
jest to, że pobiera drugi argument funkcji odwzorowującej, podczas gdy pierwszy[...iterable].map(item => item)
musiałby utworzyć tymczasową tablicę,Array.from(iterable, item => item)
co nie. Jeśli jednak nie mapujesz listy, nie ma to znaczenia.źródło
TL; DR;
Array.prototype.slice.call(nodelist).filter
Metoda slice () zwraca tablicę. Ta zwrócona tablica jest płytką kopią kolekcji (NodeList),
więc działa szybciej niż Array.from ()Więc działa tak szybko jak Array.from ()Elementy oryginalnej kolekcji są kopiowane do zwracanej tablicy w następujący sposób:
Krótkie wyjaśnienie dotyczące argumentów
Array.prototype.slice (beginIndex, endIndex)
Array.prototype.slice.call (namespace, beginIndex, endIndex)
źródło
Array.from
nie. Czas znaleźć maszynę IE. Teraz jestem naprawdę zdezorientowany, ponieważ mogłem używać Array.from w IE10 i IE11: \. Ta metoda działa w IE10 + 11, ale Array nie ułatwia mi pracy, gdy cała dokumentacja mówi inaczej.Array.from
nie działa dla mnie w IE11 Obiekt nie obsługuje właściwości lub metody „od”Array.from
zwraca również skróconą kopię. Więc nie rozumiem, jak można dojść do wniosku , że działa szybciej niżArray#slice
.Znalazłem odniesienie, które używa
map
bezpośrednio w NodeList przezArray.prototype.map.call(nodelist, fn)
Nie testowałem tego, ale wydaje się prawdopodobne, że będzie to szybsze, ponieważ powinno uzyskać bezpośredni dostęp do NodeList.
źródło
Co powiesz na to:
// 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)
Jest to takie samo podejście, jak wspomniano w dokumentacji MDN dla NodeList.forEach (w sekcji „Polyfill”), działa dla IE11 , Edge, Chrome i FF.
źródło