Есть ли более эффективный способ преобразования 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
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 даже не работают!