Introduction
jQuery is the most popular JavaScript library nowadays. It uses CSS selector style syntax to fetch elements in document object model (DOM) into wrapped element set, and then manipulate elements in the wrapped set with jQuery functions to archive different effect. Though the way of using jQuery is very easy and intuitive, we should still understand what is happening behind the scene to better master this JavaScript library.
Basic Concepts in jQuery
There are some basic concepts in jQuery should be known before we dig into the jQuery library
$/jQuery object and $()/jQuery() function
The $/jQuery object is a global object through which all jQuery functions are accessed.
It is also a function object, so the most common approach uses it is via $()/jQuery() function. $()/jQuery() function can be used to select a group of elements in DOM. It is also known as wrapper function. One simple example of using $()/jQuery() function is this
$(“#ABC”);
or
jQuery(“#ABC”);
The parameter passed into $()/jQuery() function is selector. Selector is an expression that has CSS selector style syntax. In above example, I am trying to select elements that have id equal to #ABC.
Wrapped set
Wrapped set is an array-like structure that contains all the selected DOM elements. The above $(“#ABC”) returns back a wrapped set. You can iterate over the wrapped set like an array or access individual elements via indexer. More importantly, you can apply jQuery functions against all the selected elements.
How the jQuery $()/jQuery() function works behind the scene
Because majority of jQuery function calls are started with $()/jQuery() function, so we need to understand what happening inside of it. Before go into $()/jQuery(), let’s take a look where $/jQuery object is defined. The $/jQuery object is the access point to jQuery functions. It’s a global function variable defined in jQuery. Here is the line of source code in jQuery defines it
window.jQuery = window.$ = jQuery;
The window object represents an open window in a browser, by putting $/jQuery right under window, it is defined as a global object that can be accessed in current open window.
But, what is the “jQuery” used at the end of above line of source code? It is declared in the beginning of jQuery library
var jQuery = (function() {
…
All the magic are happening inside of jQuery object declaration expression, but if look into it directly, you will get lost, so let me simplify it before we continue.
The simplified version jQuery library source code
Caveat: the simplified version is only for research purpose. It doesn’t really have all fundamental features jQuery provides. Never use it in real project.
var jQuery = (function ()
{
var k = function (selector, context)
{
var kobj = new k.fn.init(selector, context);
return kobj;
};
k.fn = k.prototype = {
init: function (selector, context)
{
if (!selector)
{
return this;
}
}
};
k.fn.init.prototype = k.fn;
return k;
})();
From the above source code, you can see jQuery function variable is defined and assigned as result of an anonymous function call.
Sidebar: How to define anonymous function
In JavaScript, you can define an anonymous function and call it right away.
For example,
(function () { alert("hello world"); })();
By putting function literal
function() { alert("hello word"); }
into parentheses
(function() { alert("hello world"); })
You can immediately invoke it with outside parentheses
|
Inside of the anonymous function, a function k is defined, it has signature like this
function (selector, context)
The first parameter is selector and the second parameter is context. In original jQuery source code, function k is actually named as jQuery that can be confused with the outer most jQuery function variable.
Inside of function k, a new instance of init function class is created and returned. The init function class is defined later on as k’s prototype method. It is a JavaScript style “class”.
After the function k declaration, an anonymous function class is defined as k’s prototype. Prototype is a special property on JavaScript’s function class that is used to point to another function object. So, all the instances of that function class will have access to member functions defined in the prototype function class. In here, init method is available by all instance of k function class. The init method has signature like this
function (selector, context)
The k’s prototype has init member method, in the meantime, init function’s prototype is assigned with k function’s prototype. This is a circular reference that usually should be avoided in normal programming practice, but, it’s the way jQuery make the return of init function can have access to all the methods defined on k.
Sidebar: Function is the first class object in Javascript
JavaScript is a functional programming style language, but the function is not a pure function in our traditional definition. The function can be created on fly, can have properties and methods, and can be passed to other functions. If you want to invoke the JavaScript function in traditional way, you can have something like this
function display()
{
alert("hello world");
}
display();
If you want to use function as class, then you can have something like this
function Car(model)
{
this.Model = model;
this.Drive = function() { alert("Go") }
}
var car = new Car("Ford");
So, the function statement is actually used to define a Car “class”. The Car class has a property Model that is initialized with parameter in function class constructor and a Drive method. So, you can create as many instance of Car class as you want. However, JavaScript’s class is not a true class because it doesn’t really have the three key characters of class in OO language.
|
The way k’s prototype function defined is called function literal. It is used widely in jQuery for different purposes.
Sidebar: Different ways defining function in JavaScript
1. Use function statement to define a function
function open() {
}
2. Use function literal to define a function
The simplest function you can define with literal is like this
var o = { }
also, you can use literal to define a function “class”
var apple = {
type: "macintosh",
color: "red",
getInfo: function() {
return this.color + ‘ ‘ + this.type + ‘ apple’;
}
}
3. Use Function object to define a function
Function Object is JavaScript built-in Object. In JavaScript, I can do this
var add = new Function(a, b, "return a + b;");
to define a function “add”. The Function will treat the first two parameters “a” and “b” as function parameters and the last parameter “return a + b” as function body.
|
After that, the internal k function is returned to outside variable jQuery. What the jQuery got is not just a k function, and also a closure that k function lived in.
Sidebar: What is closure in JavaScript
A closure is a context that created by JavaScript when returning the inside function to outside, so the inside function can still have access to those local variables.
An example of closure is like this
var addition = function(numberA) { return function(numberB) { alert (numberA + numberB); }}
so, you can create instance of addition with indicated numberA
var add2 = addition(2);
var add3 = addition(3);
add2(3);
add3(3);
|
At the end, k function is returned to the global variable jQuery.
The intricate and complex design inside of jQuery library is to make extending and using this library simple and easy. You can attach custom function to jQuery.fn to add your own business logic. And the custom function can be invoked same as built-in function by wrapped set, such as this
jQuery.fn.Test = function () { alert("Test"); }
jQuery().Test();
Summary
By understanding how jQuery works, we can better master this JavaScript library. What I am showing in this article is just a skeleton of jQuery library. After grasp the basic design principal and mechanism of jQuery library, you can look into the original source code of jQuery library to learn more on how it take advantage of variant JavaScript language features to accomplish the goal of simplicity and extensibility.