My JavaScript Code Organization Journey (So Far)

If you’ve been reading this blog, you’ll know that I’ve been doing more and more JavaScript coding recently. One aspect that’s very different to C# coding is that there’s no explicit notion of ‘public’ or ‘private’ methods. This article explains my own journey towards implementing these concepts in JavaScript.

Stage One: No Access Control, Massive Pollution

My first JavaScript files looked a lot like this:

function myPrivateMethod()
{
  ...
}

function myPublicMethod()
{
  ...
  myPrivateMethod();
  ...
}

My functions were just dumped straight into the global context, “polluting” it, and there was no kind of access control – all methods could be called from anywhere.

Stage Two: Coding-Convention Access Control, Minimal Pollution

My next strategy for defining function was to create a single object in the global scope, then add functions as properties of that object. I still hadn’t figured out access control, other than by using a naming convention:

if (typeof MyNamespace == 'undefined') {
  MyNamespace = {};
}

MyNamespace._privateMethod = function() {
  ...
}

MyNamespace.publicMethod = function() {
  ...
  MyNamespace._privateMethod();
  ...
}

While this is better than before, it’s still not true access control.

Stage Three: Access Control, Plus Namespaces

The latest way I’ve discovered for arranging code gives namespaces and true access control.

var MyNamespace = window.MyNamespace || {};

MyNamespace.MyModule = function() {

  var privateMethod = function() {
    ...
  };

  return {

    publicMethod : function() {
      ...
      privateMethod();
      ...
    }

  };
}();

I’d seen examples like the above back when I first started coding JavaScript, but I don’t like cargo-cult-copy-paste code: if I don’t understand code, I don’t use it. It’s taken me this long to understand every line in the above. Now that I do, I can start to refactor my existing code where necessary to use this pattern.

The interesting points in the above code example are:

  • The first line is a much more compact way of determining whether the single global variables is defined already (for example from another code file), and if it’s not, creating it.
  • The ‘module’ property is assigned from the immediate invocation of an anonymous function. This anonymous function returns an object whose properties are the functions we want to make public.
  • The private functions are created as inner functions of the outer anonymous function. The public functions retains access to these private functions via the magic of closures.

It continually amazes me how the JavaScript langauge manages to allow a developer so many features (in this article I’ve covered public/private and namespaces), without needing to include them as first-class keywords in the langauge.

6 Responses to “My JavaScript Code Organization Journey (So Far)”

  1. The module pattern is incredibly useful and means your code needs just one global variable for the whole of your application.

    Incidentally, I prefer to define all the properties and methods within the body of the function, then return the public ones as an object literal, e.g.


    var x = function() {

    var privateProperty = 0;

    function privateMethod() {...}

    function publicMethod1() {...}

    function publicMethod2() {...}

    return {
    publicMethod1: publicMethod1,
    publicMethod2: publicMethod2,
    alternativeNameForMethod2: publicMethod2
    }
    }

    This makes it easier to see which methods are public, change them to private, rename them, or provide alternative names.

    I’d also recommend you look into ‘prototype’ if you have not done so already.

    JavaScript is a seriously misunderstood and under-appreciated language. It’s only in the past couple of years that developers have started to realise it’s power. I really miss some of the features when I code in other languages – bring on JS on the server!

  2. Doh – looks like my code got a bit mangled. Also, I missed the “();” from the end of the outer function block. Opps.

  3. Cheers Craig, I like that idea of starting with everything private, then “exposing” particular functions.

    Classes (and maybe even inheritance) are next on my list of things to look at – but as I still mostly code in C#, my JavaScript learning is taking longer than it might. (It’s not because I’m a dolt, honest).

    I’d consider using JS server-side… but the seamless integration between C# and databases using LINQ would be tough to give up.

  4. I used JavaScript for almost 10 years before I realised what it could *really* do! Bizarrely, new techniques and concepts are discovered all the time … it’s quite strange for a language that’s been around so long.

    Classes and prototypes will be easier than you expect. There’s no ‘class’ definition, you just write a function and create object instances with ‘new’. Prototype adds further properties and methods to the base function. You can even add them after objects have been created.

    What’s also great is that everything in JavaScript is an object – even native types. You can add or adapt functionality, e.g. to add a String Trim method: String.prototype.Trim = function() { return this.replace(/^\s*|\s*$/g, ""); };

    You can now write code such as: var x = " test "; x = x.Trim();

    However, be wary about doing that if you’re integrating other people’s code. Adding further methods can effect iterations (properties such as array lengths get affected).

    Overall, it’s very powerful and I think you’ll love it, but prototypal inheritance requires your brain to be rewired in a different way to classical OOP languages.

  5. Thomas Christensen on March 2nd, 2009 at 3:38 pm

    Nice progress.

    I don’t think for MyNameSpace is better in the second version, though. It’s cleverer which equals less readable.

    It’s very tempting to make the code more compact with new tricks, esp. with tertiary operators etc., but it’s seldom desirable to do so. Maybe somebody needs to maintain the code someday. Shorter && compact != better.

    (This is by no means a bad example, I’ve seen – and written – far worse).

  6. @Thomas – my thinking behind the second version was that I should “pollute” the global namespace as little as possible – in this case, by having a single object, and putting all my stuff into that. (Hopefully one symbol is less likely to clash than hundreds).

    As I know you’ve realized, my JS skills are incomplete at the moment – this isn’t a “howto” article – it’s just a diary of my first few steps.

    @Craig – agreed, and I think the templates feature of C++ is similar in some respects… it took people a while to work out you can use them for meta-programming. “Modern C++ Design” (http://www.amazon.com/Modern-Design-Programming-Patterns-Depth/dp/0201704315) really opened my eyes to how much C++ I had yet to learn.

Leave a Reply