Not python, but let’s try something different…
One thing people don’t realize is that at the core, jQuery is based on a very simple idea that’s easy to implement but is really cool and helpful. In this article I’ll describe something others have tackled before but here’s how I approached the fundamentals of a jQuery-like lib.
What is $?
So, the entire jQuery ease of use boost comes from the very great and mysterious “$” we use all the time. But what is $? Are we extending javascript in such a way that $ is a new keyword? Well, since jQuery is just a library we obviously build off our existing notions of Javascript. This leaves us with one option.
$ must be an object. But what kind of object is it? We still can do cool stuff like:
$("#id");
So…
$ is a function
But… but how? We said it has to be an object and note that we can still do things like:
$.ajax
Well, actually, a function in Javascript is an object. Let’s see an example of what this would look like.
var $ = function(o) {
};
$.ajax = {};
The concept of jQuery
The concept of jQuery is really about that magic function we call $. We get an object/object descriptor and return a special object. These special objects are actually jQuery’s extended objects and these are the ones allowing us to make all these cool operations on elements and anything basically. They literally extend the functionality provided. The magic comes in the cool abstractions smart objects make for us like bulk changes – objects that are array of smart objects.
Simple jQuery skeleton
Here’s a simple skeleton, we’ll call our cool function _ instead of $ just for fun:
var _ = function(o) {
if(typeof o != "undefined") // Return improved object
{
var k = o; // let k be the smart/improved object
if(typeof k == "string") // object descriptor
{
k = k.substring(1,k.length);
if(o.charAt(0) == '#' || o.charAt(0) == '/' || o.charAt(0) == '.') {
if(o.charAt(0) == '#')
k = getByAttribute(k, "id");
if(o.charAt(0) == '/')
k = getByAttribute(k, "name");
if(o.charAt(0) == '.')
k = document.getElementsByClassName(k);
} else { // find object in document
k = document[o];
}
}
// extend object
if (k) {
// Array handling
if (k.length) {
if(k.length == 1) { // if a single, use only it.
k = k[0];
} else { // if multiple, extend array of objects
k.foreach = function(operation)
{
return _.foreach(k, operation);
};
}
}
k.debug = function()
{
alert(k);
};
}
return k;
}
};
_.foreach = function(v, op)
{
if (typeof op != "function") {
console.warn("[_] op is not a function!");
}
var res = [];
for(var i = 0; i < v.length; i++)
{
res.push(op(v[i]));
}
return res;
}
Note: getByAttribute() is a cross-browser function that I haven’t shown, which basically finds the element/s with the searched attribute.
While incomplete, this is a good beginning.
In this example _ returns smart objects, and has a function called foreach that does an operation for an iterable object. Each smart object has a debug() function that simply alerts itself. In addition, each smart array has a foreach() function that automatically uses _.foreach().
Summary
We now understand a little better how jQuery is made and the concepts that enable it to be this great abstraction and boosting utility with such power. $ is a constructor for these jQuery improved objects that allow us these additional functionalities. $ also serves as an object that allows for additional general functionality as well. To dive deeper I’d suggest you just go look at the code as jQuery is open source and well-documented. Last thing to cherish the brilliance that is actually in the annoying functions like the getByAttribute() we mentioned earlier. These preserve compatibility while trying to keep the performance good, and we should be greatful for the jQuery team that we don’t have to write or see that code ever again.