JavaScript is THE super-helpful programming language that makes the whole internet go.
From Google Docs to online mapping, JavaScript makes it all possible.
Despite its popularity, many concepts in JavaScript programming are rarely explained in a simple, down-to-earth way.
For example: the self-executing function.
What in the Sam Hill is that all about?!
A Normal Function
In good old-fashioned JavaScript, you have variables and functions like so:
var a = "I'm a variable"; var b = 124; function stuff(x, y) { console.log("Value of x =", x); console.log("Value of y =", y); }
Well, okay then. a and b are variables as defined. a is a string and b is an integer.
There’s also a function named stuff, but in our code above it does nothing. It just sits there waiting to be called.
Now, if we do this:
var a = "I'm a variable"; var b = 124; function stuff(x, y) { console.log("Value of x =", x); console.log("Value of y =", y); } stuff(a, b);
Then the output in our web debug console will be this:
Value of x = I'm a variable Value of y = 124
Well, that was easy…
Do self-executing functions have a death wish?
Nope. But they’re very handy!
If we rewrite stuff() as a self-executing anonymous function (also known as an Immediately Invoked Function Expression, or IIFE), the function will run itself when the JavaScript is first loaded:
var a = "I'm a variable"; var b = 124; (function() { console.log("Value of x =", a); console.log("Value of y =", b); })();
Output:
Value of x = I'm a variable Value of y = 124
Well, okay then. So a self-executing function just executes itself immediately instead of waiting to be called.
Who cares?
We do! And jQuery gives a good example of why we care…
Have you ever noticed that jQuery plugins usually have this form:
(function(jQuery) { jQuery.hotkeys = { version: "0.8", specialKeys: { 8: "backspace", 9: "tab", // ... 222: "'" }, // ... }; function keyHandler(handleObj) { // DO STUFF HERE } jQuery.each(["keydown", "keyup", "keypress"], function() { jQuery.event.special[this] = { add: keyHandler }; }); })(jQuery || this.jQuery || window.jQuery);
We know that jQuery uses $ as its primary magic mojo variable. You can do $(‘div.myclass’).hide(), for example.
If all plugins added stuff to $ (which is just a normal JavaScript object / ‘variable’), then things would get quite crowded. You also might end up breaking something!
Furthermore, we don’t need all the functions in our plugin to be available to the masses; we just want to expand jQuery’s functionality WHILE keeping the ‘core logic’ of our plugin PRIVATE from both jQuery and the end user.
This is exactly what IIFE / self-executing functions let us do in JavaScript.
So, in the above example, we have:
(function(jQuery) { // STUFF })(jQuery || this.jQuery || window.jQuery);
Here, we take the ‘global’ variable jQuery OR this.jQuery OR window.jQuery and we pass that in to our SEF/IIFE as jQuery. Don’t forget that $ = jQuery.
This isn’t really magic – it’s just ensuring that our normal jQuery $ is the same $ inside the SEF.
Moving along:
jQuery.hotkeys = { version: "0.8", specialKeys: { 8: "backspace", 9: "tab", // ... 222: "'" }, // ... };
Here we’re just defining some variables and options for our plugin which will be available at $.hotkeys.version, $.hotkeys.specialKeys, and so on.
This makes it easy to both have default options and to modify them if necessary – all in a nicely organized way.
Next:
function keyHandler(handleObj) { // DO STUFF HERE }
This function is inside our SEF, after the variables/options defined. Since we defined this function keyHandler() where we did, it WILL NOT be available to the end user or any other part of jQuery.
It’s an internal private function just for the plugin!
jQuery.each(["keydown", "keyup", "keypress"], function() { jQuery.event.special[this] = { add: keyHandler }; });
Lastly, we have this jQuery.each statement. This is where our plugin uses the same global jQuery/$ we passed in, and it attaches new event functionality for keyboard events – which is exactly the point of the plugin.
Notice that we’re adding our private keyHandler() function to the keydown, keyup, and keypress events… But keyHandler() cannot be called from any code outside our SEF/IIFE.
We could define more functions like keyHandler(), or even our own variables of any type inside:
(function(jQuery){ // DEFINE AWAY! It's private... })(jQuery || this.jQuery || window.jQuery);
When we want to make something ‘public’, we attach it to jQuery / $.
This is all super useful since our private function or variable names won’t conflict with anything in jQuery or any other plugins we use.
So, we could have 10 plugins that all define a function filter(), for example, and none of them will cause the others any problem.
So there you have it…
BTW, if you’re looking for an alternative to jQuery, check out my PikaJS library. It’s jQuery but 9X smaller and WAAAY faster – and I’m hard at work on v2.0 and 2 new plugins to go along with it!!
Recent Comments