据我了解,IE8可以访问Array.prototype.slice
方法。然而,当我尝试将其调用为NodeList
数组时,它会给我错误Array.prototype.slice: 'this' is not a JavaScript object
。 You can check it out here,或者查看我的代码:
HTML
<div id="test">Test</div>
的JavaScript
var divs = document.getElementsByTagName('div');
divs = Array.prototype.slice.call(divs);
console.log(divs);
这里发生了什么?
答案 0 :(得分:8)
更新:在某些方面可以将NodeList
视为数组 - 您实际上不必对它进行任何特殊操作,然后才能循环它,例如:
var aDivs = [];
for (var = i = 0; i < divs.length; i++) {
aDivs.push(divs[i]);
}
这将创建一个数组,其中包含您在运行document.getElementsByTagName()
有关slice
在某些浏览器中使用NodeList
而不是其他浏览器的原因的详细说明,请参阅this question,但它从规范中将这句话归结为:
切片功能是否可以成功应用于主机对象是依赖于实现的。
答案 1 :(得分:2)
错误消息准确无误 - 您的节点列表不是JavaScript对象,它是“Host Object”,您不一定会像常规JavaScript对象一样传递它。在IE8的JavaScript控制台中运行此代码:
document.querySelectorAll("div") instanceof Object
返回false
。
答案 2 :(得分:0)
我假设您希望保留相同的内容,即使NodeList集发生了变化。
如果是这种情况,坏消息:IE8坏了。它无法处理在NodeList上使用切片。
因此,您需要使用回退并在切片失败时自己制作“切片”(通过使用try / catch)。
请注意,如果您不希望更改DOM,并且类似于数组的对象就足够了,那么您可以像任何其他数组一样使用NodeList(除非它不是,并且它可能会是如果DOM改变则修改。)
[edit] 实际上它不是一个破碎的设计,它是标准所允许的(正如Kelvin Mackay评论中的链接所述)
答案 3 :(得分:0)
使用Array.prototype.slice
将NodeList
转换为数组将无法正常工作,原因如下:
slice
方法返回现有的数组元素。
Array.prototype
不是Array
对象的实例。它只是一个属性的对象容器,将由所有Array
对象实例继承。所以它没有实际的数组值。
通常使用NodeList
循环将HTMLCollection
或for...
转换为数组。但它也可以使用动态创建的一次性数组来完成:
var divs = ([]).concat(document.getElementsByTagName('div'));
也可以使用对来自Array.prototype
的方法的绑定调用来完成,尽管这不常见且不是推荐的方法。以下示例与上述基本相同。
var divs = Array.prototype.concat.apply([], document.getElementsByTagName('div'));