有更有效的方法来转换一个HTMLCollection到数组,而不是通过迭代的内容说集合和手动推每个项目到数组?


当前回答

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

将有相同的效果使用“本机”代码。

Edit

由于这得到了很多人的观看,请注意(根据@oriol的评论)下面更简洁的表达式是等效的:

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

但是请注意@JussiR的评论,与“verbose”表单不同,它确实在进程中创建了一个空的、未使用的、实际上不可用的数组实例。编译器对此的处理超出了程序员的理解范围。

Edit

从ECMAScript 2015 (ES 6)开始,还有Array.from:

var arr = Array.from(htmlCollection);

Edit

ECMAScript 2015还提供了展开运算符,它在功能上等价于Array.from(不过请注意,Array.from支持将映射函数作为第二个参数)。

var arr = [...htmlCollection];

我已经确认以上两个都可以在NodeList上工作。

上述方法的性能比较:http://jsben.ch/h2IFA

其他回答

I suppose that calling Array.prototype functions on instances of HTMLCollection is a much better option than converting collections to arrays (e.g.,[...collection] or Array.from(collection)), because in the latter case a collection is unnecessarily implicitly iterated and a new array object is created, and this eats up additional resources. Array.prototype iterating functions can be safely called upon objects with consecutive numeric keys starting from [0] and a length property with a valid number value of such keys' quantity (including, e.g., instances of HTMLCollection and FileList), so it's a reliable way. Also, if there is a frequent need in such operations, an empty array [] can be used for quick access to Array.prototype functions; or a shortcut for Array.prototype can be created instead. A runnable example:

原型机; 收集=文件。getElementById(ol).子女: 警报(的减少。呼叫(收集,(acc,发短信),i => 回回acc += 1) 的,”); < ol id =“ol”> < li > foo < / li > < li > < / li >酒吧 < li >蝙蝠< / li > < li >巴兹< / li > < / ol >

有时候,即使你以正确的方式写了代码,但它仍然不能正常工作。

var allbuttons = document.getElementsByTagName("button");
console.log(allbuttons);

var copyAllButtons = [];
for (let i = 0; i < allbuttons.length; i++) {
  copyAllButtons.push(allbuttons[i]);
}
console.log(copyAllButtons);

你得到一个空数组。 喜欢,这

HTMLCollection []
[]

Console_javascript

为了解决这个问题,你必须在html文件的body标签后添加javascript文件的链接。

<script src="./script.js"></script>

如下图所示, html_file

最终输出

HTMLCollection(6) [button.btn.btn-dark.click-me, button.btn.btn-dark.reset, button#b, button#b, button#b, button#b, b: button#b]
(6) [button.btn.btn-dark.click-me, button.btn.btn-dark.reset, button#b, button#b, button#b, button#b]

不确定这是否是最有效的,但简洁的ES6语法可能是:

let arry = [...htmlCollection] 

编辑:另一个,来自Chris_F评论:

let arry = Array.from(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的对象,但缺少很多函数定义:

类数组对象看起来像数组。它们有不同的编号 元素和length属性。但相似之处仅此而已。 类数组对象不具有Array的任何函数,而for-in 循环甚至不起作用!

我看到了一个更简洁的获取Array的方法。原型方法一般来说也很有效。将HTMLCollection对象转换为Array对象的演示如下:

[].slice.call( yourHTMLCollectionObject );

而且,正如评论中提到的,对于老式浏览器,比如IE7和更早的版本,你只需要使用兼容性函数就可以了,比如:

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

    return a
}

我知道这是一个老问题,但我觉得公认的答案有点不完整;所以我想先把这个扔出去。