Decoding jQuery – .toArray()

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)

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Technorati
  • Twitter
  • Yahoo! Bookmarks

About Shi Chuan

I am a web developer.
This entry was posted in JavaScript and tagged , . Bookmark the permalink.

6 Responses to Decoding jQuery – .toArray()

  1. Pingback: Apprendre jQuery

  2. Pingback: JavaScript Magazine Blog for JSMag » Blog Archive » News roundup: deck.js, Yahoo Kills off Maps API, Patterns for Large-Scale JavaScript Application Architecture

  3. jerone says:

    Small code correction:
    return 'I am ' + status + ' ' + this.name + ' tomorrow';

  4. Shi Chuan says:

    @jerone: thanks bro, for the correction :)

  5. TeMc says:

    [] is an array literal. So why [] instead of Array.prototype? Because Array.prototype could be overwritten by someone, but [] can’t.

    That’s not true. If one does Array.prototype.slice = function(){ return 'gotcha'; }; and then use [].slice that 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)

  6. 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

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">