Key Principles of Maintainable JavaScript

JavaScript is a curious language. It’s easy to write, but difficult to master.

The thing to remember, above all else when writing JS code, is that it’s a dynamic language. This means there are a lot of ways to do things.

This is both a blessing and a curse.

The “hardness” of JavaScript is clearly evident when considering the following image:

thegoodparts

The teeny tiny book on the left is Douglas Crockford’s MUST READ book, JavaScript: The Good Parts. Towering next to it, on the right, is, JavaScript The Definitive Guide, by David Flanagan.

One of the downfalls of how JavaScript is implemented is that it operates on top of aglobal object. In the case of browsers, this will wind up being the window object. So, anytime that code like this is present on a page…

01
02
03
04
05
06
07
08
09
10
function doStuff(){
    alert('I am doing stuff');
}
function doMoreStuff(){
   var images = document.images.length;
   console.log("There are " + images + "on this page");
}
doStuff();
doMoreStuff();

The functions doStuff and the doMoreStuff functions are immediately available to the global window object.

This means that if anyone comes along and attempts to write a function, which is also called, doStuff, there will be a conflict! All script tags are basically taking the code within them, and running it against the window in the order that they are referenced in the HTML. As a result, the second person to implement doStuff will overwrite the firstdoStuff.

A common technique for eliminating this problem is to take advantage of either self-executing anonymous functions, or namespaces. The object-oriented folks reading this are likely already familiar with the concept of a namespace, but the basic idea is to group functions into different areas for re-usability.

1
2
3
4
var NS = NS || {}; // "If NS is not defined, make it equal to an empty object"
NS.Utils = NS.Utils || {};
NS.Models = NS.Models || {};
NS.Views = NS.Views || {};

This will prevent pollution of the global namespace, and will aid in readability for your application. Now, you simply define functions in their respective namespace. A commonly defined namespace is app, which manages the rest of the application.

Another commonly used pattern is the Revealing Module Pattern.

01
02
03
04
05
06
07
08
09
10
11
12
13
NS.App = (function () {
    // Initialize the application
    var init = function () {
        NS.Utils.log('Application initialized...');
    };
    
    // Return the public facing methods for the App
    return {
        init: init
    };
}());
NS.App.init();

Above, an App function is defined within the NS object. Inside, a function variable forinit is defined, and returned as an anonymous object literal. Notice that, at the end, there’s that extra set of parenthesis: }());. This forces the NS.App function to automatically execute and return. Now, you can call NS.App.init() to initialize your app.

The anonymous function above is a best practice in JavaScript, and is referred to as aSelf-Executing Anonymous Function. Because functions in JavaScript have their own scope – i.e. variables defined inside of functions are not available outside of them – this makes anonymous functions useful in multiple ways.

01
02
03
04
05
06
07
08
09
10
11
12
// Wrap your code in a SEAF
(function (global) {
    // Now any variables you declare in here are unavailable outside.
    var somethingPrivate = 'you cant get to me!';
    
    global.somethingPublic = 'but you can however get to me!';
    
}(window));
console.log(window.somethingPublic); // This works...
console.log(somethingPrivate); // Error

In this example, because this function is automatically executed, you can pass thewindow in to the executing part }(window));, and it will be made available asglobal inside of the anonymous function. This practice limits the global variables on the window object, and will assist in preventing naming collisions.

Source: http://code.tutsplus.com/tutorials/key-principles-of-maintainable-javascript–net-25536

More: http://sparecycles.wordpress.com/2008/06/29/advanced-javascript/

http://javascriptweblog.wordpress.com/2010/12/07/namespacing-in-javascript/

http://elegantcode.com/2011/01/26/basic-javascript-part-8-namespaces/

http://thanpol.as/javascript/development-using-namespaces/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s