为什么 document.querySelectorAll 返回 StaticNodeList 而不是真正的 Array?

2022-08-30 04:31:08

这让我很烦恼,即使在Firefox 3.6中我也不能这样做,而且我仍然找不到答案,所以我想我会交叉发布这个博客中的问题:document.querySelectorAll(...).map(...)

http://blowery.org/2008/08/29/yay-for-queryselectorall-boo-for-staticnodelist/

有谁知道为什么你没有得到一个数组的技术原因?或者为什么 StaticNodeList 不能以可以使用 、 等的方式从数组继承?mapconcat

(顺便说一句,如果它只是你想要的一个功能,你可以做这样的事情......但是,为什么这个功能(故意的?)首先被阻止?NodeList.prototype.map = Array.prototype.map;


答案 1

您可以使用 ES2015 (ES6) 点差运算符

[...document.querySelectorAll('div')]

将 StaticNodeList 转换为 Array of items。

下面是一个如何使用它的示例。

[...document.querySelectorAll('div')].map(x => console.log(x.innerHTML))
<div>Text 1</div>
<div>Text 2</div>

答案 2

我相信这是W3C的一个哲学决定。W3C DOM [spec] 的设计与 JavaScript 的设计非常正交,因为 DOM 是平台和语言中立的。

像“返回一个有序”或“返回一个”这样的决策是非常有意的,所以实现不必担心根据依赖于语言的实现来对齐它们返回的数据结构(比如在JavaScript和Ruby中的数组上可用,但在C#中的Lists上不可用)。getElementsByFoo()NodeListquerySelectorAll()StaticNodeList.map

W3C的目标很低:他们会说a应该包含一个readonly .length类型的无符号long属性,因为他们相信每个实现至少可以支持这一点,但他们不会明确说索引运算符应该重载以支持获取位置元素,因为他们不想阻碍一些想要实现但不能支持运算符重载的可怜的小语言。这是贯穿规范大部分内容的流行哲学。NodeList[]getElementsByFoo()

约翰·雷西格(John Resig)提出了一个与你类似的选择他补充说

我的论点并不是说它不是很像DOM,而是它不是很像JavaScript。它没有利用JavaScript语言中存在的功能并尽其所能地使用它们......NodeIterator

我确实有点同情。如果DOM是专门用JavaScript功能编写的,那么使用起来会少得多的尴尬和直观。同时,我确实了解W3C的设计决策。