Wednesday, May 7, 2014

jQuery and Array-like objects in JavaScript

JavaScript with its closures, prototypal inheritance etc. is not the easiest language to learn. Knowing certain topics is very important in effective writing and debugging JS code. I believe that Array-like objects is one of those concepts that everyone should get familiar with. Where can we find such thing? arguments accessible inside of functions is one example. jQuery returns such animal when you call $(“someSelector”). It looks like Array, behaves (in some cases) like Array, but its not Array. Try:

var a={},b=$(“div”), c=[],d=new Array();

a instanceof Array // outputs false (duh..)
b instanceof Array // outputs false
c instanceof Array // outputs true
d instanceof Array // outputs true


c and d are arrays, a and b not so much though. a is self explanatory, its an object literal. b is Array-like object jQuery returns.

As a is furthest from what Array should look like lets try to make it closer to what arrays are. Start from beginning and attach few properties to it e.g.:

a={ 1:”first”, 2:”second”};

Now calling (e.g. in Chrome dev tools):

a

Will output:

Object {1: "first", 2: "second"}

And calling:

a[1] // outputs first

a[2] // outputs second


However:

a.length

Outputs:

undefined

And for a good reason. It is still plain object and length property doesn't exists. Ok, so lets fake it till we make it and lets add:

a.length=2;

Now calling a from console will output:

Object {1: "first", 2: "second", length: 2}

True Arrays also have number of methods so lets add some and see what happens:

a.push=function() {}

Outputs:

Object {1: "first", 2: "second", length: 2, push: function}

Not much change. The trick lies in splice method. Simply add:

a.splice=function() {}

and voila! Calling a will output:

[undefined × 1, "first"]

Now, look at our original object. Its missing “0” element hence undefined in output above. Also “second” is missing as our length was set to 2 only.

Now, can we make it even more Array-like? Sure we can! Our splice and push implementations are empty so lets fill one in, e.g.:

a.push=function(el) {
// here you can extend implementation or not, then we call Arrays push
Array.prototype.push.call(this,el);
}


Now try:

a.push(“third”);

And call:

a

Result will be:

[undefined × 1, "first", "third"]

Calling a.length will return:

3

So third element was added to our fake array. Even length property increased by one. Hows that for array? :)

All good. We got ourselves Array-Like object. a instanceof Array will still return false, but its close.

As you see jQuery isn't using any sort of black magic, and I hope this gives you better understanding of Array-like objects that you often see in JavaScript. This is only the beginning however and if you are brave and want to learn more there is no better way then try it for yourself e.g. play around with a.__proto__=[].__proto__ and var b={};b.__proto__.{}.__proto__ and such. Or try removing splice from jQuery Array-like object or .. ok I better stop now but TRY, all these are fun too!

2 comments:

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer learn from JQuery Training in Chennai . or learn thru JQuery Training . or learn thru ES6 Online Training. Nowadays JavaScript has tons of job opportunities on various vertical industry.

    ReplyDelete