1

I am new to jquery and basically, I was just looking at the source of the the get() function in jquery and it looks something like below (Jquery 11.1.3) :

get: function( num ) {
    return num != null ?

        // Return just the one element from the set
        ( num < 0 ? this[ num + this.length ] : this[ num ] ) :

        // Return all the elements in a clean array
        slice.call( this );
},

Now I understand most part of this function, I have used my basic understanding of js to make sense of what this function is doing and heres what I think, the return statement is a ternary operator that will check if num is a negative or a positive number (i.e. num < 0) , and will conclude to a given condition,

If num is a negative number this[ num + this.length ] is returned and if not

this[ num ]

will be returned , ok , fair enough , now what is the part of :

slice.call( this );

doing in this function ?

I assume it is converting a object to a array incase you pass a object instead of a pure array, I made the following function to prove my point to myself :

function get(elem) {
  return Array.prototype.slice.call( elem );
}


obj = {
  'name' : 'putin',
  'sname' : 'valdimar'
}

var str = get(obj);

console.log(str); // returns empty array. 

As you can see str is an empty array instead of being a object that is converted to a pure array. So I guess I am missing something very trivial, but can somebody now elaborate and make sense of what is slice.call(this) doing in the get() method in jquery?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Alexander Solonik
  • 9,838
  • 18
  • 76
  • 174
  • Yes, it does convert the jquery collection object to an array. However, you should try your `get` method on `{0: 'putin', 1:'valdimar', length:2}` – Bergi Jun 22 '15 at 18:02
  • @Bergi am i not trying my get method on `{0: 'putin', 1:'valdimar', length:2}` , after all i am passing `obj` inside my custom get() function . – Alexander Solonik Jun 22 '15 at 18:10

2 Answers2

4

Your assessment is correct. The jQuery object is an array-like object and get is turning the jQuery object into a true array. This is outlined in the documentation.

For slice to work on an object other than an array, that object must have property keys that are integers. It must also have a length property:

Array.prototype.slice.call({ 0: 'foo', 1: 'bar', length: 2 })
// yields ['foo', 'bar']

Or more interestingly:

Array.prototype.slice.call({ 45: 'foo', 47: 'bar', length: 48 })
// [undefined × 45, "foo", undefined × 1, "bar"]
Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • incidentally was reading a answer of yours just today , something about `draggable` , anyways , i learnt something new , did't quite understand the `more interestingly` part , can u elaborate , i'am curious , even if its not important . – Alexander Solonik Jun 22 '15 at 18:12
  • 1
    @AlexanderSolonik: Sure, that example just shows that if you specify non-consecutive integers as keys in your object, and the `length` property is large enough to accommodate them, a sparse array is created. – Andrew Whitaker Jun 22 '15 at 18:14
2

slice.call( this ); is just forcing the output to be an array, and not an Array-like object.

If you look at the entire source, slice is just this:

var slice = Array.prototype.slice;

If you'll recall, each jQuery object itself is an "array-like object", as well as NodeLists, etc. In get, they want to make sure that the output is in fact an Array.

If you have a NodeList, or a jQuery object, or a plain object, for example, and you do Array.prototype.slice.call(whateverObject), it'll force it to become an actual Array object, and you will have access to the methods of Array.prototype, like forEach, etc.

Josh Beam
  • 19,292
  • 3
  • 45
  • 68