Наиболее эффективный способ преобразования HTMLCollection в массив

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

Ответ 1

var arr = Array.prototype.slice.call( htmlCollection )

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

Edit

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

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

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

Edit

Так как ECMAScript 2015 (ред. 6) существует также Array.from:

var arr = Array.from(htmlCollection);

Ответ 2

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

let arry = [...htmlCollection] 

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

let arry = Array.from(htmlCollection)

Ответ 3

Я видел более сжатый метод получения методов 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.

Ответ 4

Для реализации кросс-браузера я бы предложил вам посмотреть 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.

Ответ 5

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

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

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

Ответ 6

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

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;
}

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

Ответ 7

Чтобы эффективно преобразовать массив в массив, мы можем использовать 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" массив", похожие на массив объекты похожи на объекты массива, но не хватает его функционального определения:

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