Фильтровать или отображать нолисты в ES6
Каков наиболее эффективный способ фильтрации или сопоставления нодлиста в ES6?
Основываясь на моих показаниях, я бы воспользовался одним из следующих вариантов:
[...nodelist].filter
или
Array.from(nodelist).filter
Какой из них вы бы порекомендовали? И есть ли лучшие способы, например без привлечения массивов?
Ответы
Ответ 1
-
[...nodelist]
создаст массив из объекта, если объект итерируется. -
Array.from(nodelist)
сделает массив вне объекта, если объект является итерируемым или если объект имеет .length
массива (имеет .length
и числовые реквизиты)
Ваши два примера будут идентичны, если существует NodeList.prototype[Symbol.iterator]
, поскольку оба случая охватывают итерации. Если ваша среда не настроена таким образом, что NodeList
является итерабельным, ваш первый пример завершится неудачно, а второй будет успешным. Babel
настоящее время Babel
не справляется с этим делом должным образом.
Поэтому, если ваш NodeList
является итерируемым, это действительно зависит от вас, который вы используете. Вероятно, я бы выбрал его в каждом конкретном случае. Одно из преимуществ Array.from
заключается в том, что он принимает второй аргумент функции сопоставления, тогда как первый [...iterable].map(item => item)
должен был бы создать временный массив, Array.from(iterable, item => item)
. Если вы не сопоставляете список, это не имеет значения.
Ответ 2
TL; DR;
Array.prototype.slice.call(nodelist).filter
Метод slice() возвращает массив. Этот возвращенный массив представляет собой мелкую копию коллекции (NodeList). Таким образом, она работает быстрее, чем ** Array.from() **
Элементы исходной коллекции копируются в возвращаемый массив следующим образом:
- Для ссылок на объекты (а не на фактический объект) срез копирует ссылки на объекты в новый массив. И исходный, и новый массив относятся к одному и тому же объекту. Если объект, на который ссылается, изменяется, изменения видны как для нового, так и для оригинального массива.
- Для строк, чисел и булевых (не String, Number и Boolean объектов) срез копирует значения в новый массив. Изменения в строке, числе или булевых в одном массиве не влияют на другой массив.
Краткое описание аргументов
Array.prototype.slice(beginIndex, endIndex)
- принимает необязательные аргументы beginIndex и endIndex. Если они не предоставлены, срезы используют beginIndex == 0, таким образом, он извлекает все элементы из коллекции
Array.prototype.slice.call(namespace, beginIndex, endIndex)
- берет объект в качестве первого аргумента. Если мы используем коллекцию как объект, это буквально означает, что мы вызываем метод среза непосредственно из этого объекта namespace.slice()
Ответ 3
Я нашел ссылку, которая использует map
непосредственно в NodeList
Array.prototype.map.call(nodelist, fn)
Я не тестировал его, но кажется правдоподобным, что это будет быстрее, потому что он должен напрямую обращаться к NodeList.