Самый эффективный способ конвертировать HTMLCollection в массив - PullRequest
296 голосов
/ 21 октября 2008

Есть ли более эффективный способ преобразования коллекции HTMLCol в массив, кроме как перебирать содержимое указанной коллекции и вручную помещать каждый элемент в массив?

Ответы [ 7 ]

535 голосов
/ 21 октября 2008
var arr = Array.prototype.slice.call( htmlCollection )

будет иметь тот же эффект, используя "нативный" код.

Редактировать

Поскольку это получает много просмотров, обратите внимание (на комментарий @ oriol), что следующее более краткое выражение эффективно эквивалентно:

var arr = [].slice.call(htmlCollection);

Но обратите внимание на комментарий @ JussiR, который, в отличие от «многословной» формы, создает в процессе пустой, неиспользуемый и действительно неиспользуемый экземпляр массива. То, что компиляторы делают с этим, находится за пределами возможностей программиста.

Редактировать

Начиная с ECMAScript 2015 (редакция 6) также существует Array.from :

var arr = Array.from(htmlCollection);

Редактировать

ECMAScript 2015 также предоставляет оператор распространения , который функционально эквивалентен Array.from (хотя обратите внимание, что Array.from поддерживает функцию отображения в качестве второго аргумента).

var arr = [...htmlCollection];

Я подтвердил, что оба из вышеперечисленных работают на NodeList.

76 голосов
/ 05 мая 2016

не уверен, является ли это наиболее эффективным, но краткий синтаксис ES6 может быть:

let arry = [...htmlCollection] 

Редактировать: еще один, из комментария Chris_F:

let arry = Array.from(htmlCollection)
19 голосов
/ 27 марта 2014

Я видел более краткий метод получения Array.prototype методов в целом, который работает так же хорошо. Преобразование объекта HTMLCollection в объект Array показано ниже:

[].slice.call( yourHTMLCollectionObject );

И, как упоминалось в комментариях, для старых браузеров, таких как IE7 и более ранних версий, , вам просто нужно использовать функцию совместимости, например:

function toArray(x) {
    for(var i = 0, a = []; i < x.length; i++)
        a.push(x[i]);

    return a
}

Я знаю, что это старый вопрос, но я чувствовал, что принятый ответ был немного неполным; так что я решил выбросить это туда, FWIW.

6 голосов
/ 09 декабря 2009

Для кросс-браузерной реализации я бы предложил посмотреть prototype.js $A function

скопировано с 1.6.1 :

function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

Он не использует Array.prototype.slice, вероятно, потому что он доступен не во всех браузерах. Я боюсь, что производительность довольно плохая, так как откат назад - это цикл javascript над iterable.

3 голосов
/ 13 августа 2016

Это работает во всех браузерах, включая более ранние версии IE.

var arr = [];
[].push.apply(arr, htmlCollection);

Поскольку jsperf все еще не работает в данный момент, вот jsfiddle, который сравнивает производительность различных методов. https://jsfiddle.net/qw9qf48j/

3 голосов
/ 16 мая 2013

Это мое личное решение, основанное на информации здесь (в этой теме):

var Divs = new Array();    
var Elemns = document.getElementsByClassName("divisao");
    try {
        Divs = Elemns.prototype.slice.call(Elemns);
    } catch(e) {
        Divs = $A(Elemns);
    }

Где $ A был описан Гаретом Дэвисом в его посте:

function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

Если браузер поддерживает лучший способ, хорошо, в противном случае будет использоваться кросс-браузер.

1 голос
/ 10 июля 2018

Для эффективного преобразования массива в массив мы можем использовать jQuery makeArray:

makeArray: преобразование объекта, подобного массиву, в настоящий массив JavaScript.

Использование:

var domArray = jQuery.makeArray(htmlCollection);

Немного больше:

Если вы не хотите сохранять ссылку на объект массива (большую часть времени HTMLCollections динамически изменяется, поэтому лучше скопировать их в другой массив, В этом примере обратите особое внимание на производительность:

var domDataLength = domData.length //Better performance, no need to calculate every iteration the domArray length
var resultArray = new Array(domDataLength) // Since we know the length its improves the performance to declare the result array from the beginning.

for (var i = 0 ; i < domDataLength ; i++) {
    resultArray[i] = domArray[i]; //Since we already declared the resultArray we can not make use of the more expensive push method.
}

Что такое массив?

HTMLCollection является объектом "array-like", массивоподобные объекты похожи на объект массива, но пропускают большую часть его функционального определения:

Подобные массиву объекты выглядят как массивы. Они имеют различные номера элементы и свойство длины. Но на этом сходство заканчивается. Подобные массиву объекты не имеют никаких функций массива, и для петли даже не работают!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...