Learning From Jquery Source

Now I’ve come up from under the crushing weight of my final year project, I finally managed to catch up with some articles/tutorials I’ve been meaning to get round to. And get round to them I did. Two of those such articles were the incredibly enlightening 10 Things I Learned From jQuery Source and 11 More Things I Learned From jQuery Source, both by Paul Irish. If you have to time, I must insist you go ahead and watch the videos (take notes) if you are at all interested in Javascript, Jqueryt. This post is my attempt at a summation of some of the more interesting points, which is are more JS specific rather than admiration of specific features of jQuery. With that said, lets begin.

1) Self-executing anonymous function

This is pretty much a basis for quite a few things in this list. If you are at all familiar with programming, the title should make sense. If not, what this means is a nameless function which is defined and calls itself immediately after its definition ends. The basic definition is:

(function(){
            // code here
            })();

There are two important points of interest here. Firstly, the brackets around the nameless function definition. This sets the function alone with a bubble as such, so no name is needed. I assume this is the same as assigning a function to variable and then calling it as somevar(); later. The second bit is the (); immediately after these brackets. This calls the function immediately after it has been defined, so this runs as soon as the browser’s engine. This is what jQuery uses to wrap around almost it’s entire library code.

But how is this useful you say? Well its an important part of the next few examples, so read on to find the use

2) Safely capture safe variables within the scope of your function

Apparently, it is perfectly possible for a user script to pop this at the top of you page

undefined = true;

Imagine the havoc that would cause a JS script! So what we do is was pass our own version through this large anonymous function.

(function(window,document,undefined){
            // code
            })(this,document);

This allows to know for certain that no malicious user scripts can mess with our window, document or undefined methods. Consequentially, this also helps with compressors and reduces load on the native JS system since we have a local snapshot of important and oft-used objects within our library or function:

(function(a,b,c){
            ...
            })(this,document);

3) Conditionals and self-executing anonymous functions

Consider:

var base = null;
            var fake = false;
            var head = // header element
            
            if(document.getElementsByTagName('base')[0]){
            	base = document.getElementsByTagName('base')[0];
            }
            else{
            	fake = true;
            	base = head.insertBefore(document.createElement('base'));
            }

We’ve all seen something like this before, where we have a conditional were the alternative option is two fold and we need some calculation. Well with the self-executing function we can make this a bit neater (depending on your preference) but processing the alternative option in said function.

var fake = false;
            var header = // header element
            
            var base = document.getElementsByTagName('base')[0] || (function(){
            	fake = true;
            	return head.insertBefore(document.createElement('base'));
            })();

Now for something completely different.

4) Nested ternary usage

Sometimes a switch statement just won’t do. Sometimes each of your multiple cases requires a slightly different test. For example consider this:

if(data === 'true'){
            	data = true;
            }else if(data === 'false'){
            	data = false;
            }else if(data === 'null'){
            	data = null;
            }else{
            	data = someFunc(data);
            }

I personally never had a problem with this sort of layered if/else if each case has complex logic to work through. But when the task at each case is pretty simple it seems that this could be streamlined. And this is what jQuery source taught me:

data = data === 'true' ? true :
            data === 'false' ? false :
            data === 'null' ? null : someFunc(data);

Of course this wouldn’t work for complex conditionals but for the meticulous programmer out there this looks quite neat.

5) Live vs Static Nodelists

This is an interesting feature of Javascript I never actually knew about. When you use the document.getElementByClass,document.getElementByTagName,document.querySelectorAll etc, you are returned a Nodelist. However, depending of which function you use, you might get a LIVE or STATIC nodelist.

Consider:

var all = document.getElementsByTagName('div'); // all is 4 at the start
            
            while(some_condition){
            	// loop adds 2 more divs
            }
            
            document.write(all); // would now write 6! updates automatically and is not a snapshot.

On the flipside, document.querySelectorAll(“div”); returns a static nodelist so it would remain 4 when additional divs were added. Clever Javascript, very clever.

Hope that was a fairly informative read, if you have time I definitely recommend watching the videos.

comments powered by Disqus