除了遍历所述集合的内容并将每个项目手动推入数组之外,是否有更有效的方法将HTMLCollection转换为数组?
Array.prototype.slice.call
并且Brave(基于Chrome 59.0.3071)在多次运行之间在两种JavaScript测试之间几乎没有区别。参见jsperf.com/htmlcollection-array-vs-jquery-children
除了遍历所述集合的内容并将每个项目手动推入数组之外,是否有更有效的方法将HTMLCollection转换为数组?
Array.prototype.slice.call
并且Brave(基于Chrome 59.0.3071)在多次运行之间在两种JavaScript测试之间几乎没有区别。参见jsperf.com/htmlcollection-array-vs-jquery-children
Answers:
var arr = Array.prototype.slice.call( htmlCollection )
使用“本地”代码将具有相同的效果。
编辑
由于这有很多观点,请注意(按@oriol的评论),以下更简洁的表达实际上等效:
var arr = [].slice.call(htmlCollection);
但是,请注意@JussiR的注释,它与“冗长的”形式不同,它确实在该过程中创建了一个空的,未使用的,实际上是不可用的数组实例。编译器对此所做的工作超出了程序员的范围。
编辑
从ECMAScript 2015(ES 6)开始,还有Array.from:
var arr = Array.from(htmlCollection);
编辑
ECMAScript 2015还提供了散布运算符,其功能等效于Array.from
(尽管请注意,它Array.from
支持将映射功能作为第二个参数)。
var arr = [...htmlCollection];
我已经确认上述两项工作都在上进行NodeList
。
上述方法的性能比较:http : //jsben.ch/h2IFA
[].slice.call(htmlCollection)
也有效。
Array.from
,即from
IE11不支持。
不知道这是否是最有效的,但是简洁的ES6语法可能是:
let arry = [...htmlCollection]
编辑:另一个,来自Chris_F评论:
let arry = Array.from(htmlCollection)
Array.from()
Array.from
,即from
IE11不支持。
我看到了一种更简洁的方法,该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
}
我知道这是一个古老的问题,但是我觉得可以接受的答案有点不完整。所以我以为我会把它扔出去。
对于跨浏览器的实现,我建议您看一下prototype.js $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;
}
它Array.prototype.slice
之所以未使用,可能是因为它并非在所有浏览器中都可用。恐怕性能会很差,因为回退是上的javascript循环iterable
。
$A
函数在大多数情况下的作用。
这是我的个人解决方案,基于此处的信息(此线程):
var Divs = new Array();
var Elemns = document.getElementsByClassName("divisao");
try {
Divs = Elemns.prototype.slice.call(Elemns);
} catch(e) {
Divs = $A(Elemns);
}
Gareth Davis在他的帖子中描述了$ 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;
}
如果浏览器支持最佳方式,可以,否则将使用跨浏览器。
[,,]
变为[undefined, undefined]
。
这适用于所有浏览器,包括早期的IE版本。
var arr = [];
[].push.apply(arr, htmlCollection);
由于jsperf目前仍处于关闭状态,因此这里有一个jsfiddle比较了不同方法的性能。https://jsfiddle.net/qw9qf48j/
var args = (htmlCollection.length === 1 ? [htmlCollection[0]] : Array.apply(null, htmlCollection));
为了高效地将类似数组的数组转换为数组,我们可以使用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"
对象,该阵列状的对象类似于数组的对象,但缺少了许多功能上的定义:
类数组对象看起来像数组。它们具有各种编号的元素和length属性。但这就是相似性停止的地方。类似数组的对象没有数组的任何功能,for-in循环甚至无法工作!
for (var a=[], i=collection.length; i;) a[--i] = collection[i];
那里没有太多的“骗子” :-)