DOM4使NodeList可迭代:
interface NodeList {
getter Node? item(unsigned long index);
readonly attribute unsigned long length;
iterable<Node>;
};
根据WebIDL,这意味着
实现声明为可迭代的接口的对象 支持迭代以获得一系列值。
注意:在ECMAScript语言绑定中,是一个接口 iterable将具有“entries”,“forEach”,“keys”,“values”和 @@iterator上的interface prototype object属性。
以下是可能的:
for (var el of document.querySelectorAll(selector)) ...
我注意到同样适用于Firefox和Chrome的HTMLCollections:
for (var el of document.getElementsByTagName(tag)) ...
事实上,我得到了
HTMLCollection.prototype[Symbol.iterator] === [][Symbol.iterator]; // true
但是,HTMLCollection未定义为可迭代:
interface HTMLCollection {
readonly attribute unsigned long length;
getter Element? item(unsigned long index);
getter Element? namedItem(DOMString name);
};
我还检查了WHATWG DOM spec,但它也不可迭代。
那么,这种行为标准与否? HTMLCollection
原型中应该有@@iterator
吗?
答案 0 :(得分:5)
我找到了它,它在WebIDL中解释了:
如果interface具有以下任何内容:
- iterable declaration
- indexed property getter和integer-typed attribute名为“length”
- a maplike declaration
- a setlike declaration
然后必须存在名称为@@iterator符号的属性, 属性{[[Writable]]: true ,[[Enumerable]]: false , [[Configurable]]: true },其值为function object。 [...]
如果界面定义了indexed property getter,那么 功能对象为%ArrayProto_values%。
在这种情况下,HTMLCollections具有索引属性getter:
getter Element? item(unsigned long index);
和名为“length”的整数类型属性:
readonly attribute unsigned long length;
因此,是的,它应该起作用。事实上,它也适用于NodeLists,即使它们没有被声明为可迭代,但它们也不会有entries
,forEach
,keys
和{ {1}}属性。正如@lonesomeday所提到的,HTMLCollection可能未被定义为可迭代,因为添加这些方法不会向后兼容,因为values
getter接受任意字符串。
答案 1 :(得分:0)
在JavaScript中,几乎所有具有iterable
结构的东西都可以通过一些迭代引擎操作,例如:for..of
和...spread
如果它返回一个[[Get]]
操作的迭代器,对它存储@@iterator
符号的属性返回一个迭代器,那么显然HTMLCollection
会返回这样一个对象。
如果迭代器具有:next() {method}:
,并且还有其他两个可选方法
return() {method}: stops iterator and returns IteratorResult
throw() {method}: signals error and returns IteratorResult
这是一个可迭代的完整自定义对象的示例。
const calculations = {
counting: 1,
[Symbol.iterator]: function(){ return this; },
next: function(){
if(this.counting <= 3){
return {
value: this.counting++,
done: false
}
}
return { value: this.counting, done: true}
}
};
const data = ...calculations; // [1,2,3]
因此,在您的情况下,只要HTMLCollection
返回正确的迭代器,您就可以应用for..of
和...spread
,但是如果您关注的是它符合规范,那么我必须告诉它你还没有计算机科学学士学位:P