In the Decoding jQuery series, we will break down every single method in jQuery, to study the beauty of the framework, as an appreciation to the collective/creative geniuses behind it.
.toArray()
As the name says, .toArray() method retrieves all the DOM elements contained in the jQuery set, as an array.
In core.js, the method was coded like below:
toArray: function() { return slice.call( this, 0 ); }
It is just a one-liner, but there are a few things to note from this simple yet clever method.
1. What is ‘slice’ in the code?
If we scroll up to around line 63 of core.js, there is a variable defined like the way below:
slice = Array.prototype.slice
So the slice is the prototype method of Array, in this case, the function can be written as:
toArray: function() { return Array.prototype.slice.call( this, 0 ); }
The slice() is a built-in method of JavaScript that selects a part of an array, and returns the new array. The first parameter specifies where to start the selection, the second specifies where to end the selection.
["ESPN", "Discovery", "CNN", "BBC"].slice(1,3); //returns ["Discovery", "CNN"]
If we omit the second parameter, it will just select everything from the start position.
["ESPN", "Discovery", "CNN", "BBC"].slice(0); //returns ["ESPN", "Discovery", "CNN", "BBC"]
2. what is ‘call’ method?
call() is a very useful build-in method of function object. One object can borrow methods from another object and use them as its own.
var meeting = { name: 'jsconf', attend: function(status) { return 'I ' + status + 'attending ' + this.name + 'tomorrow'; } } var otherMeeting = { name: 'pycon' } meeting.attend.call(otherMeeting , 'not attending'); // returns: I am not attending pycon tomorrow
In the .toArray method, we borrow the slice method from Array object and parsing in the start parameter 0. So this loops through the object and returns an array start from the first and end at the last (since it’s not specified).
3. Other uses of this clever shortcut
This pattern has been used for many projects at many places.
In HTML5 boilerplate, this is used for consolelog wrapper in plugin.js. It looks like:
var newarr = [].slice.call(arguments);
[] is an array literal. So why [] instead of Array.prototype? Because Array.prototype could be overwritten by someone, but [] can’t.
Here is another example use. If you want to write a toArray like method without jQuery, you could use querySelectorAll:
// jQuery version $('li').toArray() // querySelectorAll version [].slice.call(document.querySelectorAll('li'), 0)




Pingback: Apprendre jQuery
Pingback: JavaScript Magazine Blog for JSMag » Blog Archive » News roundup: deck.js, Yahoo Kills off Maps API, Patterns for Large-Scale JavaScript Application Architecture
Small code correction:
return 'I am ' + status + ' ' + this.name + ' tomorrow';@jerone: thanks bro, for the correction :)
That’s not true. If one does
Array.prototype.slice = function(){ return 'gotcha'; };and then use[].slicethat will actually use the gotcha-function and not the original prototype.The only reason
[]is used instead of Array.prototype is because it’s shorter and in most cases the same. When instantiating a constructor (i.e.new Array();is as literal through[]) it inherits all members from the prototype, so anything in prototype is then in the object instance. And since objects stay eternal references in JavasScript, modifying the Array.prototype at any time will screw up (or fix, depending on what you’re doing :D ) [] as well.Conclusion:
* Only count on [] as shortcut if you know for sure nobody is messing with prototypes on native objects (like Object.prototype or Array.prototype)
* Do not ever mess with prototypes on native objects (like Object.prototype or Array.prototype)
I feel that is among the most significant info for me. And i am glad studying your article. However want to remark on few common issues, The site taste is wonderful, the articles is truly nice : D. Just right activity, cheers