Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is jQuery object able to behave like an Array, even though it isn't one? [duplicate]

I always thought that jQuery $ function returns an array with jQuery methods attached to it. I want to provide some examples:

Let's say we have an array

var arr = [1,2,3];

Then we are able to add our own properties:

arr.someProp = 10;
arr.someMethod = function() { ... }

After that arr remains an array despite having custom properties:

arr instanceof Array;   //true

So, I thought jQuery object is something like arr (but more complicated) until recent experiment. I just run this code:

$('div') instanceof Array;  //false (!!!)

But it behaves like an array. It has push method, length property, that works correctly even in such case:

var $jq = $('div');
$jq.length; //3
$jq.push(123);  //wrong code, I know, this is just for test
$jq.length      //4

Also if you execute console.log($('div')), it will output something like this:

[<div></div>, <div></div>, <div></div>]

Besides jQuery object has some methods that are equal Array.prototype methods:

$('div').sort === Array.prototype.sort;     //true
$('div').splice === Array.prototype.splice; //true

My questions is: how this thing is being created?

So if you guys explain me this and provide some code samples, I would be very grateful to you.

like image 266
Oleg Avatar asked Feb 15 '23 03:02

Oleg


2 Answers

So, I thought jQuery object is something like arr (but more complicated) until recent experiment. I just run this code:

$('div') instanceof Array;  //false (!!!)

But it behaves like an array. It has push method, length property, that works correctly...

Any mutable object can "behave" like an array in the sense that the built-in Array methods will work on it, as long as it has a proper .length property and the expected numeric indices.

Take this object:

var obj = {
    "3": "buz",
    "0": "foo",
    "2": "baz",
    "1": "bar",
    length: 4
}

It's not an Array, but we can put the Array.prototype.push method on the object, and it'll work just fine.

obj.push = Array.prototype.push;

obj.push("hi");

Now the obj will have a .length of 5, and will contain the "hi" string.

like image 158
cookie monster Avatar answered Feb 16 '23 16:02

cookie monster


The jQuery object is an array-like object. It has some members that have the same purpose as the corresponding array members.

There are other array-like objects in Javascript, for example the object returned from the document.getElementsByTagName method is a HTMLCollection or a NodeList (depending on the browser), which have some members from an array, but not all.

You can create a regular object and add any members you like, and if enough of them work like the corresponding array members so that you can use it as an array in some ways, you can call it an array-like object.

Example:

var myArrayLookAlike = {
  length: 0,
  data: [],
  push: function(value){
    this.data.push(value);
    this.length = this.data.length;
  },
  pop: function(){
    var value = this.data.pop(value);
    this.length = this.data.length;
    return value;
  }
};

The jQuery library has the makeArray method that can be used to create a real array object from an array-like object, which can be used when an array-like object lacks some specific members that a method needs to use it.

like image 45
Guffa Avatar answered Feb 16 '23 16:02

Guffa