Есть ли более эффективный способ преобразовать HTMLCollection в массив, кроме как перебирать содержимое указанной коллекции и вручную помещать каждый элемент в массив?
392
Есть ли более эффективный способ преобразовать HTMLCollection в массив, кроме как перебирать содержимое указанной коллекции и вручную помещать каждый элемент в массив?
for (var a=[], i=collection.length; i;) a[--i] = collection[i];
так что не так много «против» там :-)Array.prototype.slice.call
и Brave (на основе Chrome 59.0.3071) практически не имеет различий между двумя тестами javascript на нескольких запусках. См. Jsperf.com/htmlcollection-array-vs-jquery-childrenОтветы:
будет иметь тот же эффект, используя "родной" код.
редактировать
Так как это получает много просмотров, обратите внимание (на комментарий @ oriol), что следующее более краткое выражение эффективно эквивалентно:
Но обратите внимание на комментарий @ JussiR, который, в отличие от «многословной» формы, создает в процессе пустой, неиспользуемый и действительно неиспользуемый экземпляр массива. То, что компиляторы делают с этим, находится за пределами возможностей программиста.
редактировать
Начиная с ECMAScript 2015 (ES 6) существует также Array.from :
редактировать
ECMAScript 2015 также предоставляет оператор распространения , который функционально эквивалентен
Array.from
(хотя обратите внимание, чтоArray.from
в качестве второго аргумента поддерживается функция отображения).Я подтвердил, что оба вышеперечисленных работают
NodeList
.Сравнение производительности для упомянутых методов: http://jsben.ch/h2IFA
источник
[].slice.call(htmlCollection)
тоже работает.Array.from
, То естьfrom
, не поддерживается IE11.не уверен, что это наиболее эффективно, но краткий синтаксис ES6 может быть таким:
Редактировать: еще один, из комментария Chris_F:
источник
Array.from()
Array.from
, То естьfrom
, не поддерживается IE11.Я видел более краткий метод получения
Array.prototype
методов в целом, который работает так же хорошо. ПреобразованиеHTMLCollection
объекта вArray
объект показано ниже:И, как упоминалось в комментариях, для старых браузеров, таких как IE7 и более ранних версий, вам просто нужно использовать функцию совместимости, например:
Я знаю, что это старый вопрос, но я чувствовал, что принятый ответ был немного неполным; так что я решил выбросить это туда, FWIW.
источник
Для кросс-браузерной реализации я бы предложил посмотреть на функцию prototype.js
$A
скопировано с 1.6.1 :
Вероятно, он не используется,
Array.prototype.slice
потому что он доступен не во всех браузерах. Я боюсь, что производительность довольно плохая, так как откат назад - это цикл javascriptiterable
.источник
$A
функция делает большую часть времени.Это мое личное решение, основанное на информации здесь (эта тема):
Где $ A был описан Гаретом Дэвисом в его посте:
Если браузер поддерживает лучший способ, хорошо, иначе будет использовать кросс-браузер.
источник
[,,]
становится[undefined, undefined]
.Это работает во всех браузерах, включая более ранние версии IE.
Поскольку jsperf все еще не работает в данный момент, вот jsfiddle, который сравнивает производительность различных методов. https://jsfiddle.net/qw9qf48j/
источник
var args = (htmlCollection.length === 1 ? [htmlCollection[0]] : Array.apply(null, htmlCollection));
Для эффективного преобразования массива в массив мы можем использовать jQuery
makeArray
:Применение:
Немного больше:
Если вы не хотите сохранять ссылку на объект массива (большую часть времени HTMLCollections динамически изменяется, поэтому лучше скопировать их в другой массив, в этом примере обратите особое внимание на производительность:
Что такое массив?
HTMLCollection является
"array-like"
объектом, массив подобных объектов похож на объект массива , но отсутствует много его определение функционально:источник