Каков наиболее эффективный способ фильтрации или сопоставления нодлистов в ES6?
Основываясь на моих чтениях, я бы использовал один из следующих вариантов:
[...nodelist].filter
или
Array.from(nodelist).filter
Какой из них вы бы порекомендовали? А есть ли способы лучше, например, без использования массивов?
javascript
arrays
filter
ecmascript-6
nodelist
Кристоф
источник
источник
babel
, тогда[...coll]
просто вызоветArray.from(coll)
все, что не являетсяArray
....
синтаксис может не поддерживаться старыми IDE, покаArray.from()
это обычный метод.Ответы:
[...nodelist]
сделает массив из объекта, если объект является итеративным.Array.from(nodelist)
сделает массив из объекта, если объект является повторяемым или если объект подобен массиву (имеет.length
числовые реквизиты)Ваши два примера будут идентичны, если они
NodeList.prototype[Symbol.iterator]
существуют, потому что оба случая охватывают итерации. Если ваша среда не была настроена таким образом, чтобы ееNodeList
можно было итерировать, ваш первый пример завершится ошибкой, а второй - успешным.Babel
в настоящее время не обрабатывает это дело должным образом .Так что, если ваш
NodeList
итеративный, действительно зависит от вас, что вы используете. Скорее всего, я выберу в индивидуальном порядке. Одним из преимуществArray.from
является то, что он принимает второй аргумент функции сопоставления, тогда как первый[...iterable].map(item => item)
должен был бы создать временный массив, ноArray.from(iterable, item => item)
этого не сделал . Однако, если вы не отображаете список, это не имеет значения.источник
TL; DR;
Array.prototype.slice.call(nodelist).filter
Метод slice () возвращает массив. Этот возвращаемый массив представляет собой неглубокую копию коллекции (NodeList),
поэтому он работает быстрее, чем Array.from (),поэтому он работает так же быстро, как Array.from ()Элементы исходной коллекции копируются в возвращаемый массив следующим образом:
Краткое объяснение аргументов
Array.prototype.slice (beginIndex, endIndex)
Array.prototype.slice.call (пространство имен, beginIndex, endIndex)
источник
Array.from
нет. Пора найти машину IE. Теперь я действительно запутался, потому что смог использовать Array.from в IE10 и IE11: \. Этот метод работает в IE10 + 11, но меня не облегчает работа с Array.from, когда вся документация говорит об обратном.Array.from
у меня не работает в IE11 Объект не поддерживает свойство или метод fromArray.from
также возвращает мелкую копию. Поэтому я не понимаю, как вы пришли к выводу, что он работает быстрее, чемArray#slice
.Я нашел ссылку, которая используется
map
непосредственно в NodeList поArray.prototype.map.call(nodelist, fn)
Я не тестировал его, но кажется вероятным, что это будет быстрее, потому что он должен напрямую обращаться к NodeList.
источник
Как насчет этого:
// 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)
Это тот же подход, который упоминается в документации MDN для NodeList.forEach (в разделе «Polyfill»), он работает для IE11 , Edge, Chrome и FF.
источник