在 NodeList 上使用 'for ... of' 时边缘 15 抛出错误

Edge 15 throws error when using 'for ... of' on a NodeList

查看 ECMAScript compatibility table 时,它说 Edge 15 和 Edge 16 支持 for ... of 循环。

然而,当我运行这段代码时:

const list = document.querySelectorAll('[data-test]');
console.log(list);

for (const item of list) {
  console.log(item);
}
<div data-test></div>
<div data-test></div>
<div data-test></div>
<div data-test></div>
<div data-test></div>

它适用于 Chrome 和 Firefox,但不适用于 Edge。相反,它说:

Object doesn't support property or method 'Symbol.iterator'.

按我的理解,NodeList其实应该支持吧?

这是一个可以自己尝试的字段:Test it online

有人可以解释这里的问题或错误吗?

Edge 确实支持 for... of

它似乎不支持 NodeLists 上的迭代器。并非所有类数组对象都支持迭代器,我不确定是否有任何标准说明 NodeLists 必须支持。

无论如何,让 for ... of 与他们一起工作很容易:

const list = document.querySelectorAll('[data-test]');

for (const item of Array.from(list)) {
 console.log(item);
}
<div data-test>a</div>
<div data-test>b</div>
<div data-test>c</div>
<div data-test>d</div>
<div data-test>e</div>

如果支持 for..of 但 Edge 15 忘记将行为添加到 NodeList,您可以用很少的代码自己填充它:

NodeList.prototype[Symbol.iterator] = function* () {
    for(var i = 0; i < this.length ; i++) {
        yield this[i]
    }
}

要回答另一个问题(它在规范中定义为可迭代的吗?)答案是:

DOM 规格 defines NodeList 为:

interface NodeList {
  getter Node? item(unsigned long index);
  readonly attribute unsigned long length;
  iterable<Node>;
};

注意第三个 属性、iterable<Node>;。查找 in the WebIDL spec:

In the ECMAScript language binding, an interface that is iterable will have “entries”, “forEach”, “keys”, “values” and @@iterator properties on its interface prototype object.

Edge 似乎没有实现任何这些。