Preparing Yourself for Modern JavaScript Development

There is a lot going on in the JavaScript world these days, both in and out of the browser. Talk about script loaders, client side MVC frameworks, minifiers, AMD, Common.js, Coffeescript, can quickly get your head spinning. And for those people who are completely immersed in that world, it can be easy to forget that the vast majority of JavaScript developers today haven’t heard of any of these tools, and in fact, they likely aren’t even equipped to try these tools.

This post is going to be an attempt to simply address some of the low hanging fruit out there, and try to bring together a few different concepts that a developer should understand before they go out and try to tackle something like Backbone.js or Ember.js. Once you understand most of the concepts in this post, then you can go out and approach more advanced JavaScript topics with a bit of confidence. This post does assume that you have developed with JavaScript before, so if you haven’t, then you might be better off starting with something a bit more basic. With that out of the way, here we go!

Modules

How many of you are working with an application that has JavaScript that looks like this just sitting in a file (notice I didn’t say embedded in your html files, there is no good excuse for that):

var someSharedValue = 10;
var myFunction = function(){ //do something }
var anotherImportantFunction = function() { //do more stuff }

If you’ve made it to this point in the post, then most likely you are dealing with (or creating) code that looks like this. I’m not judging you, I wrote code like that for a really long time. The problems here are many, but the one that we are going to focus on is the pollution of the global namespace. When writing code like this, you are just shoving all of these methods and variables into the global namespace. We need some way to keep this kind of data out of the global namespace, and the technique we are going to use here is the module pattern. There are different forms that modules can take, but I’m going to start off with the easiest method that you can start using today, an IIFE (Immediately Invoked Function Expression).

It is a big name, but the implementation is very simple:

(function(){
  //do some work
})();

If you haven’t used an IIFE before this might look at bit weird at first. There are a lot of parentheses going on around here! Basically we have an anonymous function with a set of parentheses following it which cause the function to be immediately invoked. So we are creating the function, then immediately calling it. Hence the “immediately invoked function” part of the name. The “expression” part of IIFE comes from the fact that we need to turn this into an expression and not a statement, since a function statement must have a name. We do this by adding the extra set of parentheses around the outside. This also gives us an easy way to spot IIFE’s when looking through our code.

Now that we know how to implement it, let’s talk about why we do this. In JavaScript all we have to work with for scoping is functions, and so if we want to create scope, we use a function. By executing code inside of the IIFE we are scoping all variables and functions inside of the IIFE and so we aren’t polluting the global namespace. The only problem is that all variables we create are now scoped inside of the function, so if we want to access them outside of the global scope, we need to get them into the global namespace, or at least into something that is in the global namespace.

One thing we can do is to use the window object and assign any functions or values to this object, which allows us to call these methods externally. In order to guarantee that nothing messes with the window variable, we can pass the window object as a parameter to our IIFE. We can do the same thing with references to libraries or even the value ‘undefined’. Our IIFE ends up looking like this:

(function(window, $, undefined){
  //do some work
})(window, jQuery);

As you can see, we are passing in the window and jQuery variables (the jQuery $ variable is just an alias for the ‘jQuery’ variable, and we use it here in case another library has redefined the $ variable), but then we have three parameters going into the method. The idea is that since we aren’t passing a third parameter, it ends up being undefined, so we get a variable called ‘undefined’ local to the method that is guaranteed to actually have the value ‘undefined’, in case another piece of JavaScript modified it. Notice that we could call any of these values within the function without passing them in, this works because functions in JavaScript form closures where they “close over” the outer scope that they reside in. This topic can be an entire post, and I have written one which explains closures in terms of C#, but the concepts are very similar.

Now we have a a method which is executed immediately, has a much safer execution context containing valid window, $, and undefined variables (it is still possible that something could have reassigned one of these variables before we hit this script, but it is much less likely). We are in a pretty good place, having saved our code from becoming a bunch of clutter in the global namespaces and reducing the potential for collisions with other JavaScript running in our application.

At this point anything we want to export from the module we are just assigning direction to the window object. But often I don’t want to just assign everything in my module directly to the window object, I want to have some way of grouping functionality. In most languages we call these containers namespaces, and we can emulate them in JavaScript using objects.

Namespaces

If we wanted to declare a namespace, and assign a function to it, we could do something like this:

window.myApp = window.myApp || {};
window.myApp.someFunction = function(){
  //so some work
};

We are merely creating an object in the global namespace by checking to see if the object already exists, and if so we use it, otherwise we create a new object using the object literal notation: {}. At this point we could just start building up the namespace by assigning functions like we are doing above, but we don’t want our code just hanging out there, we want to combine our namespaces with our modules, like this:

(function(myApp, $, undefined){
  //do some work
}(window.myApp = window.myApp || {}, jQuery));

This could also be written like this:

window.myApp = (function(myApp, $, undefined){
  //do some work
  return myApp;
})(window.myApp || {}, jQuery);

Now, instead of passing in window to our module, we are passing in a namespace object that is hanging off the window object. The reason we assign it using || is so that if we use this namespace in multiple places we will end up using the same object over and over instead of creating a new object each time which would clear out our namespace. Many libraries include namespace functions which will create namespaces for you, or you can use something like namespace.js which allows you to easily create nested namespaces. I generally try not to create deeply nested namespaces, since in JavaScript you have to specify the namespace on every item that is in the namespace. So if you created a “doSomething” method in the MyApp.MyModule.MySubModule namespace, you would either have to reference it like:

MyApp.MyModule.MySubModule.doSomething();

every time you called it, or you would have to alias the namespace inside of your module by doing:

var MySubModule = MyApp.MyModule.MySubModule;

This way you would only need to say “MySubModule.doSomething()”. It just makes things more complicated, and unless you have a ton of code, it can be unnecessary.

Revealing Module Pattern

There is another pattern that you’ll often see being used to create modules, and it is called the revealing module pattern. This pattern is just a different approach to creating a module, letting you define everything privately inside of the module, then expose what you want to expose by returning an object which has references to everything you want to expose publicly. Let’s take a look at how you would define this:

var myModule = (function($, undefined){
  var myVar1 = '',
  myVar2 = '';

  var someFunction = function(){
    return myVar1 + " " + myVar2;
  };

  return {
    getMyVar1: function() { return myVar1; }, //myVar1 public getter
    setMyVar1: function(val) { myVar1 = val; }, //myVar1 public setter
    someFunction: someFunction //some function made public
  }
})(jQuery);

As you can see, we are creating a module in one pass which makes it more simple, and then we are returning an object which exposes the pieces of our module that we are interested in making public, while allowing us to keep our private variables hidden. The variable “myModule” is going to contain the two publicly exposed items, but as you can see, “someFunction” uses “myVar2”, but it is not externally accessible.

Creating Constructors (Classes)

In JavaScript we don’t have classes, but we can create objects, and we do this by creating a constructor function. Let’s say that we wanted to create a bunch of Person objects, and we wanted to pass in a first name, last name, and age. We could define our constructor like this (we would most likely put this inside of a module):

var Person = function(firstName, lastName, age){
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
}

Person.prototype.fullName = function(){
  return this.firstName + " " + this.lastName;
};

Looking at just the first function for now, you’ll see that we are creating a Person constructor. This is what we will use to build new person objects. It takes three parameters and it assigns them all to the execution context from the current invocation of the constructor. This is how we get public instance variables. We could create private variables here too, by assigning the constructor parameters to local variables inside of the constructor, but the problem becomes that public methods can’t access those variables, and so you’re probably better off making them all public. You can create methods inside of the constructor which are publicly accessible, and can access the private variables, but they create a whole different set of problems.

Next you’ll see that we accessing the “prototype” of the Person constructor. The prototype of a function is an object that all instances of a function will go to when trying to resolve fields or functions called on the instance. So what we are doing here is creating a single instance of a “fullName” method that all instances of “Person” can access without having a ton of instances of “fullName” hanging around. We could have defined “fullName” inside of the constructor as “this.fullName = function() { …” but then every person would have another copy of the fullName method, which is not what we want.

If we wanted to start creating people, we could do so like this:

var person = new Person("Justin", "Etheredge");
alert(person.fullName());

If we wanted to, we could also create another constructor that inherits from the Person constructor. Let’s say we wanted to create a Spy constructor, that would build an instance of Spy, but would only declare a single method:

var Spy = function(firstName, lastName, age){
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
};
Spy.prototype = new Person();

Spy.prototype.spy = function(){
  alert(this.fullName() + " is spying.");   
}

var mySpy = new Spy("Mr.", "Spy", 50);
mySpy.spy();

As you can see, we are creating a constructor that looks just like the person, but then we are settings its prototype to an instance of the Person constructor. Now we can add methods, and when we create an instance of Spy, it can access methods in the Person constructor, and the methods can access variables which were assigned in the Spy instance! It is a bit convoluted, but once you get past the details, it is pretty elegant.

Wrapping It Up

At this point, if you have learned something, then awesome! But unfortunately we really haven’t touched on any “modern” JavaScript development. All of the topics that we have gone over in this blog post are relatively old, and have been in fairly wide use for at least the last few years. But now hopefully you are at least heading down the right road. Now that you are splitting up your code into modules and using lots of different files (you should be!), the next step for you should be to start researching JavaScript combination and minification. If you are a Rails developer, and are using Rails 3, then you get all of this for free in the asset pipeline. If you’re using .NET then you can look at the framework that I started, SquishIt. If you’re using ASP.NET MVC 4, then it also has some built in combination and minification support.

Hope this helped, and I hope to see you back here next time when I will start to explore a few topics in modern JavaScript development!

Be Sociable, Share!

68 comments

  1. Hi,

    Came here from HN. Am new to programming and javascript. I managed to make some sense of this, so thank you for that.

    can you tell me what the performance implications are of some of these techniques.

    I know performance is a big deal these days, and the way that scripts are called and executed makes a big difference to performance.

    Would you be willing to elaborate?

    Thanks

  2. Justin Etheredge

    @Khuram Thanks for the compliments! While I appreciate your concern about performance, I’m going to somewhat sidestep the issue and give you a few things to think about:

    1) The most expensive thing you can do in the browser is DOM manipulation. Most of these techniques are just raw JavaScript creating basic objects.
    2) Performance metrics are impossible for browsers. Every browser reacts differently in memory, speed, etc… All you can do is test.
    3) Even with JavaScript, I would err on the side of maintenance and readability, versus raw speed. These techniques are widely used, and shouldn’t be big performance drains, but I will pose a question to you. What are the downsides of not using these techniques or a large JavaScript codebase? I would say that those downsides far outweigh any minuscule perf gains you might get.

  3. @Justin , Thanks for responding so soon and elaborating.

    I’ll keep in mind DOM manipulation going forward.
    I didnt realise that different browsers have different performance metrics. That is very new to me, but thank you for this information.

    The reason i ask about performance is that, we have a web app (our startup) where we help children with their learning for maths and other related educational games, and we get visitors from all over the globe and locations with subpar internet access such as Peru and remote parts of India. So having a site with optimal performance really matters to us.

    We’ve made many performance improvements such as introducing css sprites for images and using CDNs for serving static content and so on, but for us every little helps.

    here is the link, just out of interest: http://www.freeteacher.co.uk

    My quest for speed isnt a person quest, it’s for the sake of a great user experience for the children.

    At the same time, i’m making my own foray into simple web app development (i’m going to be using node.js) so i’m going to keep your tips in mind for development.

    Hope you dont mind my calling on you for a code review at some point?

  4. Using RequireJS with AMD is a much better solution than using Namespace.

    You only require two globals (require/define) and then everything is proteced using modules.

    http://requirejs.org

  5. why do we “need” namespaces in JavaScript ?

  6. Shouldn’t this:
    (function(){
    //do some work
    }());

    be this:
    (function(){
    //do some work
    })();

    ?

  7. Justin Etheredge

    @Andre Yep, my goal was to introduce a few basic concepts, and not get caught in the quagmire of introducing too many new concepts. I’ll get to those in a future post.

  8. Justin Etheredge

    @Erhan I guess we technically don’t, but then everything gets shoved in the global scope.

  9. Justin Etheredge

    @Wix Either will work fine.

  10. @Wix @Justin …but the latter will not pass in JSLint

  11. Justin Etheredge

    @Devgutt Excellent point, I’ll update it.

  12. I highly recommend following CommonJS modules and packages specs for modern develipment. using require statements without maintaining namespaces is a big life saver.

    check out OneJS: http://github.com/azer/ onejs

  13. commonjs modules are the way to go, AMD is codesmell, all this manual closure stuff is codesmell

  14. @Khuram Some quick simple advice for people new to javascript.

    1) if you see yourself using the jquery constructor multiple times on the same element/selector, store it in memory. So something like:

    var val = $(“#myID”).val();

    var html = $(“#myID”).html();

    should be:

    var myDiv = $(“#myID”);

    var val = myDiv.val();
    var html = myDiv.html();

    2) Learn about the various performance issues associated with each selector. ID and Class selectors (“#id” or “.class”) are faster since they make use of the native browser’s getElementById and getElementByClass functions.

    3) Read up on and use event delegation and bubbling link: http://stackoverflow.com/questions/1687296/what-is-dom-event-delegation

    4) Make sure to use some sort of html templating if you are planning to build html with javascript as inserting html into the DOM using javascript is expensive (and leads to a lot of cluttered code if done incorrectly). I personally like to use Mustache.js (https://github.com/janl/mustache.js/) created by one of the github founders.

    Good Luck!

    @Erhan If you are building rather large javascript heavy web applications, you need to be careful not to clutter up the global namespace as that could lead to unexpected clashes.

  15. @TJ,

    Considering the Browser enviroment:

    How CommonJS can be better to develop than AMD?

    Do you know what global’s are?

  16. Nice read! I always like to mention the common convention of aliasing a constructors prototype with fn when teaching JS. Always seems to connect the dots for jQuery devs.

    Person.fn = Person.prototype;

    Person.fn.fullName = function(){
    return this.firstName + ” ” + this.lastName;
    };

  17. @Andre

    I’m answering for TJ; CommonJS does not force you to pollute global scope.

    Check out OneJS; http://github.com/azer/onejs

    It sandboxes all the client-side project into single global variable.

  18. CommonJS is impossible to hand to a browser without preprocessing it into something more painful to debug.

    AMD isn’t codesmell. It’s adding a fundamental concept of modularization to browser-based JavaScript, and that belongs in the browser, not a server. You don’t get that for free at this stage.

    Besides, how obtrusive is this?
    define(function(require, exports, module) {/* Your module here! */});

  19. Justin, really well-written article. I do a lot of js/jQuery development, and I really like your approach to bringing people up to ‘that next level’. Kudos.

  20. Great article, Justin. Gives a really solid overview and gets the developer ready for the next step.

  21. Brian, CommonJS modules don’t need preprocessing! Tools like OneJS just put a library on top of your code and sandbox your code in a smart way! do you guys want to cover your all modules with sphagetti code manually? is this what a coder should do? you will not be able to reuse your code in other platforms like nodejs. by the way, amd is retarded, seriously.

  22. Tarun Elankath

    Lovely summary. One gets to know JS patterns as one reads and writes JS code but I so wished I had a single page like this when I was starting out.

  23. @azer,

    You can reuse CommonJS code into the browser, and with better debugging.

    Also it’s easier to load only a subset of the entire code base, and only fetch the rest when needed.

    Debugging one huge javascript file it’s like debugging C code but reading assembly. You can do it, but you don’t want to.

    YUI, Dojo (even jQuery) allow some kind of async module loading.

    I don’t mean that CommonJS is bad, in fact the syntax is much better than AMD, but CommonJS require the module to loaded sync and browsers don’t like that.

  24. I haven’t dug too deep into it, but OneJS looks like a server-side tool for preprocessing CommonJS files into something a browser can use. How’s that any different from Browserify?

    I don’t want to depend on a special server to load JS modules in my browser, period. Make browser stuff happen in the browser, make server stuff happen on the server.

  25. @Andre,

    This is what you RequireJS guys can’t understand; optimization is not a trade off for this case!

    You CAN split your build code to different pieces (e.g packages) and load it later and/or have debug mode for your development time! It’s a work that should be done after you have reusability between platforms and cheap maintainability first! RequireJS is an EVIL project that tries to make decisions instead of coder and force people to maintain stupid headers. It’s completely insane. What does make it easy to debug?

    Please look at this code;

    https://gist.github.com/1286969

    If you need to load some pieces of this code later, just decide what part of your code should be loaded later and load it when needed, like following;

    $(“#open-foobar”).click(function(){

    loadPackage(“foobar”, function(error){

    myproject.navigate(“foobar”);

    });

    });

    That’s all.

  26. @Brian,

    OneJS is not a server-side tool. It’s a command-line tool that sandboxes your NodeJS structured code by writing module headers instead of you and putting a small library on top of your code.

    Browserify is not a complete implementation, just lets your js assets have require functions with an awkward implementation and pollutes global scope a lot.

    By the way, I first wrote a build tool for CommonJS two years ago and it lets you split your code to many pieces, read: http://jsbuild.kodfabrik.com

    I don’t maintain it anymore since it’s Python and not a good implementation. But even that project was producing unobtrusive code.

  27. @azer,

    Sorry, I tried to read the +/- 300 lines of code from the link (https://gist.github.com/1286969) but I didn’t undestand where the project code are, only it’s name (exampleProject). It start’s at line 142 right?

    Also, I think you didn’t undestand what I tried to say.

    CommonJS is a very good solution but not for the Browser, it’s model don’t fit in the model of the Browser.

    “reusability between platforms”: you are assuming that everybody uses NodeJS on the server, which isn’t true.

    “cheap maintainability first”: like I said, debugging the code that look’s like what I wrote it’s easier than a combined output of lot’s of files.

  28. What is the difference between using the prototype technique you showed and this:

    var Person = function (){
    this.Save = function() { … };
    };

    var person = new Person();
    person.Save();

  29. @Andre,

    CommonJS fits any kind of platform very well, if you do the right abstractions. I’ve been following RequireJS for two years and I remember the first poor implementation of it which tries to implement CommonJS by forcing you cover your code with some awkward stuff. I can’t belive they couldn’t make forward move for almost three years and there are more people who still believe their bullshit and let them make decisions instead of themselves.

    “you are assuming that everybody uses NodeJS on the server, which isn’t true.”: I assume CommonJS is being used by everybody in server-side platforms. And it should be. NodeJS doesn’t require you to code something specific for NodeJS, like the other retarded projects such as RequireJS.

    ” like I said, debugging the code that look’s like what I wrote it’s easier than a combined output of lot’s of files.” And I’m repeating, you can have debugging mode and make it easier to debug. I first wrote a bundling tool for CommonJS that allows you to split your code by default; http://jsbuild.kodfabrik.com I coded that tool two years ago in Python and don’t maintain it anymore. Making a single-file JS file easier to debug is a separate problem that can be solved in such an easy way.

  30. Also, if you’re interested on more about IIFEs, check out my blog post:

    http://benalman.com/news/2010/11/immediately-invoked-function-expression/

  31. Amazing post! I will look forward to new JavaScript posts…

  32. Bryan Paronto

    @ Wix. This it didnt pass JSLint because Douglas Crockford prefers to put last set of parens inside rather than outside. He’ says they look like ‘dog’s balls’.

  33. Although I understand what is happening when you specify undefined as a parameter and it’s not being defined, I don’t understand why one would do that. It is common to encounter libraries or environments that redefine the meaning of undefined?

  34. Does Crockford still maintain JSLint personally?

    I heard him make the “dog balls” reference a few days back over at PayPal. I was puzzled, as it only looks like one set of parens. But that’s not my dog.

    What’s got me torn these days, ideologically JS-wise, is whether ‘prototype’ is a good idea or just the Biggest Security hole Ever. Is subclassing really used all THAT often, other than in class assignments and a few UI types?

  35. […] Preparing Yourself for Modern JavaScript Development | CodeThinked […]

  36. @Aymeric,

    The difference is that your example creates one instance of the Save function for each Person object. There is only ever one instance of the prototype so only one copy of the Save function.

    @Kevin Bjorke

    prototypes are useful even without inheritance as a way of sharing properties between multiple objects.

  37. wow, javascript is an ass ugly language … how can people stand working with it?

  38. Dojo+Coffeescript is great!

  39. That was an excellent read. Many thanks indeed.
    I urge you to complete this series with as many articles as you can. I’m a veteran developer (Java) and JavaScript is quite scary without such great posts like this one.

  40. […] Delicious: Preparing Yourself for Modern JavaScript Development | CodeThinked Very good article of some Javascript programming patterns that are important and well explained. Great for someone looking to take their JS skills to the next level., Do you really need jQuery (for mobile dev)? | Matteo Spinelli’s Cubiq.org Great rundown of how to accomplish a lot of what jQuery gives you with plain old Javascript. Always feels good to do it the low-level way when you can, especially when doing a small task or a mobile app. […]

  41. What is the advantages between prototype compared to json method ?
    I’m actually doing the json method:
    var myClass = {
    myVar: ‘test’,
    myMethod: function() {
    return this.myVar;
    }
    }
    var test = myClass.myMethod();

    Everything is public, but is it that bad ?

  42. It would be better if you provided usage samples for all those module pattern implementations

  43. Thanks for such a nice post. I didn’t find the namespce implementing there in any sample. Although you have used namespaces there to call the functions but namespace definition id still missing.

  44. I’ve never seen the point of using IIFE. Instead of

    (function(){
    //do some work
    })();

    Why not just

    // do some work

    It is actually 2 lines less coding!!! Instead of

    (function(a,b){
    //do some work
    })(c,d);

    Why not just use c and d instead of internally calling them a and b?

  45. A well–written post that highlights the key concepts for doing JS app-dev. And I like that last Namespace pattern!!!

  46. Brandon Wittwer

    Great article. I’ve been writing a knockoutJS app with these “faults” all showing. I don’t have much inheritance or repeated object classes so the prototype thing may not make a big impact for me, but what I want to ask is…. When it comes to memory management… If I put everything in one global namespace is there any reason to expect a memory leak? Im. I’m. It using IIFE, but since everything lives in one global variable, that shouldn’t cause memory leaks right? Ff handles things fine, but ie hates it after a while. I’m also doing lots of DOM manipulation with knockout at the wheel and I worry that jquery + .data + knockout templating engine might be hurting me in the memory department too.

    Sorry somewhat off topic, but advice is repaid in eternal indebtedness… Which is always fun.

  47. Please tell that “Out of the Browser”, where javascript is used?, as you said in 1st sentence.

  48. Make sure you check out
    http://benalman.com/news/2010/11/immediately-invoked-function-expression/

    If you are unclear about IIFE and why you would use them.

  49. @CUP
    If you don’t see the use it means that you don’t do big projects in JS, that means you don’t need to do it now.
    In PHP or other languages what is the use of having class ?
    It’s just easier to read and organize your code ! And this is extremely important !
    Imagine you got the function “jump()”, and your program has 20 js pages, where are you going to find that function ?
    now if you got “Action.jump()” and a page that is named Action.js, is it easier ?
    You also organize it like this
    Action.jump() Action.walk() Action.run() etc…
    You know that this class does these specific things.
    How would you do the same without it ?

  50. A'braham Barakhyahu

    Good article. Good to see your quality posts back Justin. I remember Thomas Fuchs mentioning inline script tags being faster for mobile apps because it removes additional request. I wonder if this is still the case. Interesting (and passionate) discussion on Commonjs and Requirejs modules. Wonder if the are any posts comparing and contrasting these two.

Leave a Reply

Your email address will not be published. Required fields are marked *