2

许多 JavaScript 库(jQuery、Zepto)似乎在 querySelectorAll()、getElementsByTag 或 ClassName 结果上调用 Array.prototype.slice.call...

通过阅读 StackOverflow 上许多类似的问题/答案,我确实明白它会将 NodeList 结果转换为真正的 Array,以便您可以对 NodeLists 上不可用的结果调用 Array 方法(切片、弹出) - 但我没有'不明白是为什么?您通常不需要在 DOM 节点列表上进行切片/弹出 + NodeLists 已经具有长度属性,因此无论如何它们都是可遍历的。

一些答案似乎暗示这是因为 NodeList 指向活动的 DOM 对象。但是如果你把它转换成一个数组,引用仍然指向活动的 DOM 节点——那么有什么区别呢?

还是我完全想念的其他东西?它是否有助于 Zepto/jQuery 以某种方式缓存 DOM 元素的多个属性调用?(虽然我真的不明白,因为这些仍然是实时的 DOM 引用)

4

2 回答 2

2

您通常不需要在 DOM 节点列表上进行切片/弹出

实际上,你这样做了,这正是它有必要的原因。

例如, , 等如何.eq()工作.first()。jQuery 对象包含一个数组中的副本NodeList然后各个方法获取该数组的切片。同样,您不能将.add()节点连接到NodeList.

此外,即使其中的元素随后从 DOM 中删除,这些数组也需要保持有效。数组中的引用仍然有效,可用于将这些元素重新插入 DOM。

如果你只有一个 liveNodeList元素,当它们从 DOM 中删除时,它们会自动从列表中消失,并且会永远丢失,除非你对它们有单独的引用。

于 2012-11-08T18:39:09.717 回答
0

...因为 NodeList 指向活动的 DOM 对象...

不,这是个误会。关键不是列表中的每个节点都是“活”的 DOM 对象(真实但不相关),而是列表本身是“活的”。换句话说,只要 DOM 发生更改,列表的内容就可能随时更改(甚至增长或缩小)。

如果您对列表中的项目执行更改 DOM 的操作,则列表本身可能会在您使用它时即时更改。这意味着您的代码在幕后可能会遇到非常奇怪的递归和/或性能问题,而您却没有意识到这一点,而且源代码中几乎没有任何迹象。

将 NodeList 转换为常规的 Javascript 数组会消除列表本身的这种“活跃性”,从而消除了自取其辱的机会。

于 2013-11-19T20:40:48.070 回答