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


当前回答

这适用于所有浏览器,包括早期的IE版本。

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

由于jsperf目前仍处于关闭状态,下面是一个比较不同方法性能的jsfiddle。https://jsfiddle.net/qw9qf48j/

其他回答

这适用于所有浏览器,包括早期的IE版本。

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

由于jsperf目前仍处于关闭状态,下面是一个比较不同方法性能的jsfiddle。https://jsfiddle.net/qw9qf48j/

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

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]
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

对于跨浏览器的实现,我建议你看看prototype.js $ a函数

从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循环迭代。

这是我个人的解决方案,基于这里的信息(这篇文章):

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

如果浏览器支持最好的方式,否则将使用跨浏览器。