Array.prototype.slice.call() & wrapper.querySelectorAll() 有啥作用?

Posted

技术标签:

【中文标题】Array.prototype.slice.call() & wrapper.querySelectorAll() 有啥作用?【英文标题】:What does Array.prototype.slice.call() & wrapper.querySelectorAll() do?Array.prototype.slice.call() & wrapper.querySelectorAll() 有什么作用? 【发布时间】:2013-10-06 14:36:15 【问题描述】:

我在一个 js 插件中发现了以下锥体

var container = document.getElementById( 'vs-container' ),
wrapper = container.querySelector( 'div.vs-wrapper' ),
sections = Array.prototype.slice.call( wrapper.querySelectorAll( 'section' ) ),
links = Array.prototype.slice.call( container.querySelectorAll( 'header.vs-header > ul.vs-nav > li' ) );

我不明白Array.prototype.slice.call()wrapper.querySelectorAll( 'section' ) 在上面的代码中做了什么。我以前没有见过它们,所以我想知道它们实际上是做什么的。

【问题讨论】:

【参考方案1】:

querySelectorAll 是 DOM 元素上的一种方法,它接受 CSS 选择器并返回匹配元素的静态 NodeList

Array.prototype.slice.call 是将NodeList(其作用类似于数组,但没有Array.prototype 中的方法)转换为真实数组的一种方法。

在浏览器控制台的此页面上尝试一下!

> var headers = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
undefined
> headers.map(function(el)  return el.textContent; )
TypeError: Object #<NodeList> has no method 'map'
> headers = Array.prototype.slice.call(headers);
…
> headers.map(function(el)  return el.textContent; )
["What does Array.prototype.slice.call() & wrapper.querySelectorAll() do?", …]

【讨论】:

【参考方案2】:

它从任何类似数组的东西创建一个数组(例如,具有length 和名称为01 等的属性)。你会看到很多 getElementsByTagName 之类的,它们会返回实时的 NodeList 实例。 querySelectorAll 没有必要这样做,因为这会返回非实时列表,除非您当然想要 Array 的所有功能。

Array.prototype.slice.call(...) 看起来有点吓人,但实际上很简单:数组从对象 Array.prototype 获取方法。其中之一是 slice 方法,它返回数组的一部分的副本。如果您不给slice 任何参数,它会返回整个数组的副本。但棘手的一点是,当您调用slice 时,您不必在数组上调用它,只要看起来像数组即可。当您在 javascript 中使用 Function#call 时,您可以在调用中设置 this 的内容。所以Array.prototype.slice.call(resultFromQuerySelectorAll)调用slicethisquerySelectorAll的结果; slice 然后很乐意为您提供一个包含这些条目的数组。

【讨论】:

以上是关于Array.prototype.slice.call() & wrapper.querySelectorAll() 有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章