4

I found following cone in a js plugin

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' ) );

I couldn't understand what does Array.prototype.slice.call() & wrapper.querySelectorAll( 'section' ) do in above code. I've not seen them before so I would like to know what they actually do.

2 Answers 2

4

querySelectorAll is a method on DOM elements that accepts a CSS selector and returns a static NodeList of matching elements.

Array.prototype.slice.call is one way to turn that NodeList (which acts like an array, but doesn’t have the methods from Array.prototype) into a real array.

Give it a try on this page in your browser’s console!

> 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?", …]
Sign up to request clarification or add additional context in comments.

Comments

2

It creates an array from anything array-like (e.g., that has a length and properties with names like 0, 1, etc.). You see it a lot with getElementsByTagName and such, which return live NodeList instances. It's not really necessary with querySelectorAll, because that returns non-live lists, unless of course you want all the features of Array.

That Array.prototype.slice.call(...) can look a bit intimidating, but it's actually quite simple: Arrays get their methods from the object Array.prototype. One of those is the slice method that returns a copy of a portion of the array. If you don't give slice any arguments, it returns a copy of the entire array. But the tricky bit is that when you call slice, you don't have to call it on an array, just something that looks array-like. When you use Function#call in JavaScript, you can set what this is within the call. So Array.prototype.slice.call(resultFromQuerySelectorAll) calls slice with this being the result from querySelectorAll; slice then obligingly gives you an array with those entries.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.