Why do Array.prototype.slice.call(nodeList) for DOM elements?

前提是你 提交于 2021-02-05 07:34:45

问题


Lots of JavaScript libraries (jQuery, Zepto) seem to be calling Array.prototype.slice.call on querySelectorAll(), getElementsByTag or ClassName results...

From reading many many similar questions/answers on StackOverflow I do understand that its to convert a NodeList result to a real Array so that you can invoke Array methods (slice, pop) on the results which are not available on NodeLists - but what I don't understand is why? You don't usually really need slice/pop on a list of DOM nodes + NodeLists already have a length property so they're traversable anyway.

Some answers seem to imply that its because a NodeList is pointing to live DOM objects. But again if you convert it to an Array, the references are still pointing to live DOM nodes - so whats the difference?

Or is it something else that I'm completely missing? Does it help Zepto/jQuery to somehow cache multiple property calls for DOM elements? (although I don't really see how since those are still live DOM references)


回答1:


You don't usually really need slice/pop on a list of DOM nodes

Actually, you do, and that's exactly why it's necessary.

For example, how else would .eq(), .first(), etc. work. The jQuery object contains a copy of the NodeList in an array, and then the individual methods take slices of that array. Similarly, you can't .add() nodes to a NodeList.

Furthermore, those arrays need to remain valid even if the elements therein are subsequently removed from the DOM. The references in the array are still valid, and can be used to reinsert those elements back into the DOM.

If all you had was a live NodeList the elements would automagically disappear from the list when they're removed from the DOM, and would be lost forever unless you had a separate reference to them.




回答2:


...because a NodeList is pointing to live DOM objects...

No, this is a misunderstanding. The key is not that each of the nodes in the list is a "live" DOM object (true but irrelevant), it's that the list itself is "live" . In other words the contents of the list may change (or even grow or shrink) at any time whenever the DOM is changed.

If you perform operations on the items in the list that change the DOM, the list itself may change on the fly while you're using it. That means under the covers your code can get into really weird recursion and/or performance problems, without you realizing it and without hardly any indication in the source code.

Converting the NodeList to a regular Javascript Array removes this "liveness" of the list itself, and thus removes the opportunity to shoot yourself in the foot.



来源:https://stackoverflow.com/questions/13295361/why-do-array-prototype-slice-callnodelist-for-dom-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!