Cracking JavaScript Idioms

Teaching you the art of decyphering hard-to-read JavaScript Idioms.

JavaScript idioms are concise and effective solutions, but they are potentially difficult to understand. JavaScript, being an extremely flexible language, offers many opportunities to create useful idioms. Exploring these idioms is beneficial and fun!



Essentials


A great way to learn JavaScript is by reading the code of libraries and frameworks written by expert developers, such as, jQuery, Mootools, Dojo, Backbone, ExtJs, Ember, and many others. Exploring these sources will reveal many programming gems which you then add to your own bag of coding tricks and techniques. It takes time but it is well worth the effort.

JavaScript is a language of great flexibility and while spelunking these libraries and frameworks you will most likely encounter code that you wonder: what in the world is going on here? You feel confident with the JavaScript syntax and all of a sudden you run into a statement that totally throws you off; either 1) it does not makes sense (i.e. what does this mean), or 2) you know what it means, but you have no idea why anyone would do this. Here is an example of each (from real-world code):

options || (options = {});    // what does this mean?

var _true_ = true;            // why would anyone do this?

It is hard to discern what the first line does, and, as far as the second example, why would anyone reassign true? It takes time and experience to decipher these idioms which is the topic of this section.

What exactly is an idiom? According to Wikipedia it is "an expression of a simple task, algorithm, or data structure that is not a built-in feature in the programming language being used, or, conversely, the use of an unusual or notable feature that is built in to a programming language". Then it goes on: "The term can be used more broadly, however, to refer to complex algorithms or programming design patterns. Knowing the idioms associated with a programming language and how to use them is an important part of gaining fluency in that language."

An example of an idiom in the English language is "It's raining cats and dogs". It is a short and effective way of saying that it rains very hard. Any native speaker will understand this, but those that are not are left wondering what the heck they are talking about.

Programming idioms are concise and effective solutions. The problem in JavaScript is that they can be rather obscure and therefore they frequently throw off beginning, and sometimes even experienced JavaScript developers. In this section we will list and explain some of the more common idioms (some may refer to these as hacks). This will prevent you from scratching your head when examining someone else's code and spend time searching for an answer. It actually is a fun section.

Most JavaScript idioms are very short and terse. They are used for a variety of reasons: for instance, they 1) make the code more effective and/or efficient, 2) allow you to do things that are not natively supported by JavaScript, 3) reduce the code size which in turn reduces the download times, 4) allow the minifier to further reduce the code size, and 5) raises the 'cool factor' of the author. The last reason is disappearing quickly as the entire JavaScript community is catching up by learning to read and understand these 'hacks'.

Going back to patterns, there is a continuum of patterns from high to low level. At the highest level we have architecture patterns, in the middle we have design patterns, and at the lowest level we are finding idioms. Idioms are sometimes referred to as mini patterns. All of these are discussed in this package. Architecture patterns in the Architecture Patterns and MV Patterns sections. Design patterns in the Modern Patterns and Classic Patterns sections. Finally, idioms are discussed in the rest of this section.

Let's look at some JavaScript idioms.

The && and || operators
In JavaScript the && (and) and || (or) operators behave in ways that some developers may not expect. First, they short-circuit evaluations and secondly they return the last evaluated value (not necessarily true or false).

Short-circuiting is a way for the JavaScript engine to increase performance. With &&, when the first operand evaluates to false, then the second operand is not executed because the result will always be false. Similarly, with ||, when the first operand evaluates to true, then the second operand is not executed because the result will always be true. Here is an example of each:

if (true || (a + b))     //  => a + b will never execute
if (false && (a + b))    //  => a + b will never execute

JavaScript developers use this feature to avoid the 'object has no properties' error. This error occurs when you request the value of a property on an object that does not exist. This is what that looks like:

if (obj && obj.Property) var a = obj.Property;

This code first checks whether obj is undefined (i.e. does not exist); if so, short-circuiting will stop any further execution. Next it checks whether obj.Property is undefined. If so, it also stops further execution. Only when obj.Property is defined will it execute the code block in which its value is assigned to variable a.

Many developers do not realize that in JavaScript logical expressions with && and || do not return true or false; instead, they return the value of the last expression that was evaluated. For example: false || "8" will return "8". Similarly, "apple" && true, returns "apple" and not true (because of short-circuiting).

Despite these unexpected return values, these conditions mostly behave as expected because if-statements only look for 'falsy' and 'truthy' expressions (falsy and truthy are explained in the next section).

Again, JavaScript developers are using this behavior to their advantage by writing shorter code. At the beginning of a function you frequently see these kinds of code:

param = param || '';

Or

param || (param = ''};

Both do the same: they assign a default value to an undefined parameter – an empty string in the examples. Note that this also works when param is false, null, or 0 as these are all considered 'falsy'.

These lines are shorthand for this ternary expression:

param = param ? param : '';

If you wish to check param only for undefined then you need something like this:

param = (typeof param !== "undefined") ? param : '';

Let's say you have three node objects. If you need a property from one of three node objects you could use this shorthand:

var count = (node1 || node2 || node3).count();

It uses the fact that the conditional expression returns a node object and not true or false. If you don't know this then the above expression can be rather puzzling.

Combining && and || allows you to shorten your code, but possibly at the cost of readability:

return tree && tree.nodes && tree.nodes.length || 0;

Here we check that tree and its nodes property are defined. If so, return the number of nodes, else return 0, thus ensuring that the return value is always numeric.

Falsy and Truthy
Most languages have a Boolean data type that is either true or false (or 1 or 0). Whatever the true and false values are, there is no ambivalence about which is which: true is true and false is false (not true). JavaScript's built-in Boolean type works exactly like this.

However, JavaScript is a flexible language and true/false evaluations are often less clear. First of all we have dynamic types, meaning a variable type can change type at any time. A string, for example, can be changed to a number, a Boolean, an object, and even a function, at runtime. Secondly, as we demonstrated before, logical statements work perfectly fine with any type, they don't have to be Boolean at all.

Developers use the terms 'falsy' and 'truthy' to denote the falseness or truthiness of an expression. The rules are as follows: 'falsy' expressions include those that evaluate to false, null, undefined, the empty string, the number 0, and NaN (not a number, which is a special number). Everything else is considered 'truthy', including Infinity, objects, functions, and arrays, whether they are empty or not.

These rules can lead to confusing code, like this:

if ("sidewalk") {
    alert("sidewalk" == false);  // => false
    alert("sidewalk" == true);   // => false
}
Run

Note that the words truthy and falsy are not official terms but they are broadly understood in the JavaScript community.

Double exclamation (!!)
Here are a couple examples of code you may run into with double exclamation marks:

var state = !!options.overlay;

return !!result;

You may look at this code for a while and perhaps conclude that it does nothing; it simply reverses a Boolean value and then it reverses it back to the original value. However you would be wrong, because in JavaScript the double !! is used to ensure that what is returned is truly a boolean type.

The first ! will evaluate the truthy-or falsy-ness of the expression and return a boolean. Remember that falsy values include: false, null, undefined, the empty string '', the number 0, and NaN. Everything else is truthy. The second ! will then reverse the boolean value and returns a true boolean.

Here is an example where a numeric value is coerced into a boolean value using !!

var odd = !!(number % 2);

Again, this can be tricky to decipher; only when you know what the purpose of the !! is can you make sense of it.

The $ and _ identifiers
In JavaScript, identifier names (e.g. variables, object, and functions) must start with $, _, or a letter. The remaining characters can be $, _, letters, and numbers. An identifier cannot start with a number.

Given these rules, both $ and _ are valid identifiers. When you first encounter these you may be wondering what they mean. They look particularly odd when combined with dot notation as in $.fn.tooltip() and _.pluck(). Because of their uniqueness, different libraries have been 'competing' for these names.

The jQuery library, for example, uses $ as a shortcut to their core jQuery() function. Some other libraries such as Prototype and Mootools also use the $ identifier. As far as using the _, we are aware of only one library that claims this name, which, naturally, is called underscore.js.

In the section on Namespaces (in the Modern Patterns section) we discuss how using the same global identifier becomes a problem for developers using multiple libraries in their web pages. Fortunately, library authors have come up with a workaround convention by implementing a noConflict() method which allows developers to select what $ means at any point in their own script. This will be discussed further under the Namespace pattern in the Modern Patterns section.

Assign globals to locals
Sometimes you see code like this in JavaScript modules (the Module pattern is described in the Modern Patterns section).

function () {
    var oProto = Object.prototype,
        aProto = Array.prototype,
        fProto = Function.prototype;

     // ...
     
})();

In this code the prototypes of built-in Object, Function, and Array are assigned to local variables. The main reason for doing this is to assist the minifier in further reducing the code size. The minifier cannot change the name of native JavaScript objects and its members (nor can it change any reference to a 3rd party library).

However, by assigning the reference to a local variable (just once), you allow the minifier to minify the local variable at all locations that it is used. For instance, each Object.prototype reference gets reduced to x (if this is the minifier's assigned name). This is the Minification idiom whereby you structure your code for maximum compression.

You may also see this:

(function () {
    var slice = Array.slice,
        unshift = Array.unshift,
        toString = Object.toString,
        hasOwnProperty = Object.hasOwnProperty;

    // ...

})();

There are two reasons for doing this: it speeds up access to built-in prototype methods and it facilitates further minification. Perhaps a slight disadvantage is that, in the case of functions, they need to be invoked using a call or apply method, for example:

slice.call(array, 0, n);

hasOwnProperty.call(obj, key); 

Alternatively, you may see the pattern below. It may look a bit odd, but the end-result is exactly the same as the example above. The only difference is that literal object expressions and literal array expressions are used rather than their type names. This one is a bit slower than the one above because new array or object instances are created on each line.

(function () {
     var slice = [].slice;
     var unslice = [].unslice;
     var toString = {}.toString;
     var hasOwnProperty = {}.hasOwnProperty;

     //...

}();

In computational or graphics libraries you may find code that looks like this:

(function () {
var math = Math,
    mathRound = math.round,
    mathFloor = math.floor,
    mathCeil = math.ceil,
    mathMax = math.max,
    mathMin = math.min,
    mathAbs = math.abs,
    mathCos = math.cos,
    mathSin = math.sin,
    mathPI = math.PI

    //...

}();

Again, the authors are creating fast-access references to frequently used native methods. Having local variables prevents the JavaScript engine from having to search the prototype chain for these frequently used types and methods. This is particularly beneficial for methods and properties that are on the global object because it is always the last searched object in the prototype chain. Examples include Document, Math, and alert.

Finally, you may run into code that looks like this:

(function () {
    var _true_ = true,
        _false_ = false,
        _null_ = null;

    // ...

})();

This may not be obvious at first, but it allows the minifier to reduce the length of native variable names, shaving off extra bytes from the JavaScript files being downloaded.

Bonus arguments
Functions in JavaScript come with two bonus arguments: this and arguments. They are not visible in the formal parameter list, but are passed by the compiler and are available within the scope of the function. As you know, this references the current object context, meaning the object it is currently working on. This can be a built-in object or your own custom object. By default, global functions have the global object as their context, whereas methods that are part of an object will have their object as the current context. The Invocation pattern, which is part of the Modern Patterns section, has a lot more to say about the value of this.

The other bonus argument is named arguments. It has a list of arguments that were provided with the invocation. It looks like an array, but it is not because other than length and item(index) it is lacking all array methods. One of the first things you see done in many functions is that the incoming arguments object is transformed into an array. The code looks like this:

function func(a, b, c) {
    var args = [].slice.call(arguments, 0);
    
    // ...
}

Or this:

function func(a, b, c) {
    var args = Array.prototype.slice.call(arguments, 0);
    
     // ...
}

Both statements convert arguments to an array. The first example uses an array literal. Its slice method is explicitly called with arguments entered as the this value and 0 as the begin argument into slice. The second does exactly the same with slightly different syntax. It explicitly includes 'prototype' to speed up the JavaScript engine because we know that the built-in slice method lives on the array's prototype. Not including prototype will return the same results, like so:

function func(a, b, c) {
    var args = Array.slice.call(arguments, 0);
    
    // ...
}

Now, with all arguments stored in an array we have full access to the built-in array methods.

It is interesting to note that the argument feature allows you to declare functions without any parameters and then invoke these with any combination of arguments. Inside the function you can then use the arguments bonus variable to determine the arguments passed in. The disadvantage of course is that your arguments are not assigned a name.

There may be a use case for not declaring parameters when you don't know what arguments to expect, but generally it serves little purpose other than making functions more obscure. However, this feature does highlight the highly flexible and forgiving nature of JavaScript functions.

Placeholder parameters
Sometimes you need to declare a parameter that is not used. This is the case when your code is invoked in a certain way but you have no use for the argument provided. Examples are callback functions and try-catch exception blocks. You could name the parameter notUsed, blah, xyz, or ex in the case of try catch. A common and more expressive way of doing this is by using an underscore (_) which is a valid identifier name in JavaScript.

The beauty is that arguments are visible only locally, that is, within the function body, so their names do not interfere with variables on the global object namespace. If it did, this would be a problem because there is a popular library called underscore.js which, uses the underscore (_) as its alias (similar to $ and jQuery). Here is how you use this placeholder parameter:

function myCallback(_, result) {
    // ...
}

And

try {
    // ...
} catch(_) {
    // do not respond to an exception
}       

So, now when you see an underscore parameter, you can be pretty certain it is unused.

Function overloading
JavaScript does not natively support function overloading. Function overloading allows you to create functions with the same name but with different signatures. A function signature is the combination of arguments, their types and the order in which they appear (in some languages it also includes the return data type).

As an example, createUser(first, last) is different from createUser(age, name, street). These function are said to be overloaded and the runtime determines which function to call, based on the arguments provided.

In JavaScript this does not exist. When invoking a function, any number of arguments is accepted as well as any argument data type. So, JavaScript is just fine when invoking a function with any number and any type of arguments irrespective of the function definition. It won't even complain.

This flexibility allows us to mimic function overloading. Here is how this works. You create a single function and immediately inside this function you check the arguments and their types. If they do not match the 'default' argument pattern (signature) you switch them around and adjust them to another signature. Here is an example:

var animate = function (delay, callback, size)

    // potentially switch arguments

    if (isFunction(delay)) {  // test for function
        callback = delay; 
        size = callback; 
        delay = 100;             // default delay
    }

    // execute according to default pattern 
}

var isFunction = function (item) {
    return Object.prototype.toString.call(item) == "[object Function]";
}

// can be invoked in two ways
animate(2000, function () { alert('hi'); }, 200);

animate(function () { alert('hi'); }, 200);

The animate function expects 3 arguments of type: number, function, and number. However, it can also be called with 2 arguments: function and number. The function first checks if the first argument is a function. If it is then it swaps the arguments until they match the default signature. The missing delay is given a default value of 100. Next, it continues executing based on the default parameter pattern.

Alternatively, you could check the arguments coming in and then build a switch statement calling any number of appropriate helper functions (possibly nested methods).

Options hash
The Options hash idiom is designed to create better function signatures and APIs in general. Here is the problem. Suppose you write a constructor function that creates a new element to be placed onto the HTML document:

var Element = function (type, content, width, height, margin, padding, border, background) {
     // code goes here
};

As a client of this function you have to provide 8 arguments and they must be in the correct order or else unexpected things start to happen. Furthermore, some may be optional whereas others are required. It is common to have the required parameters first followed by the optional ones, so you can do things like:

var element = new Element("TextBox", "Joe", "200px");

The remaining 5 parameters will be undefined and the function can check for arguments that are undefined or null and set these to reasonable default values.

Now assume that you only have argument values for type and padding, the first and sixth argument. Your function call will look something like this:

var element = new Element("TextBox", null, null, null, null, "12px", null, null); 

This is an awful way to program, as well as very error prone.

Fortunately an elegant idiom exists that will greatly improve the API. It is called Options hash. It has also been referred to as the Configuration pattern.

Options hash allows you to pass all optional arguments in a single object. It works like this: you partition the parameters in two groups: required and optional. The required ones are placed at the beginning of the parameter list. All optional parameters are captured in a single parameter, usually called options or settings. This options parameter is an object with name/value pairs that include all optional parameters. Any arguments that the caller cannot provide can be skipped.

Let's apply this pattern to improve our Element function. We have only one required parameter and the remainder is optional, so the function signature can be changed to this:

var Element = function (type, options) {
     // code goes here
};

That looks much better. In fact, the options parameter itself is optional, so only the first argument is required.

Here are a few examples of how you can invoke this function:

var button = new Element("Button", {content: "Submit", padding: "8px"});
var textbox = new Element("TextBox", {width: "120px", height: "22px", border: "1px"});
var checkbox = new Element("Checkbox");

Nice. But how do you handle this inside the function? First you create an object with reasonable default values for each optional parameter. The Element function will look like this:

var Element = function (type, options) {
    var defaults = {
        content: null,
        width: "120px",
        height: "20px",
        margin: "3px",
        padding: "2px",
        border: "0px",
        background: "white"
    };

    // more code here
};

Next, you extend the default object with the incoming options argument. Extending means that you copy all properties from one object to another object. You can use the jQuery extend method or write your own (it is fairly simple). Here we use jQuery extend:

var Element = function (type, options) {
    var defaults = {
        content: null,
        width: "120px",
        height: "20px",
        margin: "3px",
        padding: "2px",
        border: "0px",
        background: "white"
    };

    this.type = type;
    this.settings = $.extend({}, defaults, options);
};

The extend method starts with an empty object (the object literal) and extends it with the properties of the default values and then overwrites only the ones that are provided in the options parameter: very elegant.

Remember that the options parameter itself is optional. How do we handle the situation that it is not provided? Here is how:

var Element = function (type, options) {
    var defaults = {
        content: null,
        width: "120px",
        height: "20px",
        margin: "3px",
        padding: "2px",
        border: "0px",
        background: "white"
    };

    this.type = type;
    this.settings = $.extend({}, defaults, options || {});

};

All we did was add || {}. This checks if the options argument value is falsy (null or undefined). If so, it returns an empty object. Finally, if you prefer, you can also place the default values inline as an extend argument.

var Element = function (type, options) {
    this.type = type;
    this.settings = $.extend({}, {
        content: null,
        width: "120px",
        height: "20px",
        margin: "3px",
        padding: "2px",
        border: "0px",
        background: "white"
    }, options || {});

    // your code here
};

This idiom is also called the Configuration pattern because it is frequently used to configure an object. In these scenarios you may see the options parameter named as settings, configuration, or something similar. Also, it is not necessarily the case that all items in this object are optional, some libraries that use this idiom require the client to provide at least some values. In the jQuery Patterns section we will see an example of this.

Immediate functions
The frequently-used Module pattern (discussed in the Modern Patterns section) is usually implemented as an anonymous immediate (self-executing) function that contains the entire code base for the module. The general format looks like this:

(function () {
  // code goes here..
}());

The term immediate function is commonly used and describes it well. We will use this term throughout this package. However, you should be aware there are other names including: self-executing anonymous function and self-invoked anonymous function. More recently we are seeing IIFE being used as an abbreviation for immediately invoked function expression.

There are many different ways to create immediate functions. When you see the different varieties for the first time they may leave you puzzled until you realize that these are just different ways to ensure that the enclosing function immediately executes. Here we list some of these varieties. Note that, at the end, they all do the same thing, that is, they immediately execute the function. Whichever you choose is your personal preference, although the one above is the more common approach.

Let's start with a slight variation, by rearranging the brackets at the end. Note that the effect is the same. Crockford and his JSLint tool do prefer the first syntax as he feels that it more clearly indicates the result of a function being invoked (rather than the function object itself). Here it is:

(function () {
  // code goes here..
})();

The next one is also becoming popular and this is how Facebook implements the module pattern. It creates an immediate function by placing a leading ! in front of the function keyword instead of having surrounding brackets.

!function () {
  // code goes here..
}();

You can also explicitly call the function immediately with a call method. The advantage of using call is that you have the option to control the function's scope by passing a different argument. This is explained later in the Invocation pattern in the Modern Patterns section.

(function () {
  // code goes here..
}).call();

Another variety is with a + or - before the function name. This one can leave you really confused.

+function () {
  // code goes here..
}();

Finally, let's go totally crazy and see some other valid options:

~function () {
  // code goes here..
}();

Or

delete function () {
  // code goes here..
}();

Or

void function () {
  // code goes here..
}();

Or

100% function () {
  // code goes here..
}();

Some developers will actually use these exotic constructs in their programs; possibly to show off their developer 'chops'. Of course, this will make it very difficult for anyone who comes after them that needs to maintain their code long after they have left the project.

You may be wondering how these strange constructs work. The answer will help you decipher other weird varieties in case you run into these. To understand the mechanics of these activations, let's start off with a normal function declaration.

function go() {
  // code goes here..
}

This function has a name, go in this case, and will be loaded at compile time into memory. It will execute whenever it is called; simple enough.

Below is a function declaration without a name, a so-called anonymous function. It is somewhat pointless to do this as there is no way to reference and execute it anywhere in the program.

function () {
  // code goes here..
}

By placing parenthesis around the declaration we group what is inside and it gets treated as an expression, but without any side effects. JavaScript is happy, but nothing happens.

(function () {
  // code goes here..
})

We can call the above function expression by placing parenthesis at the end (possibly with arguments). This will create an immediate function that executes as soon as the compiler encounters it.

(function () {
  // code goes here..
})();


There are other ways to turn an anonymous function declaration into an expression. For example by prefixing it with a ! (not operator) or + (add operator) or ~ (bitwise NOT operator) which are the tricks we have seen before. When adding () at the end, the expression executes immediately. It is important to know that there are no side effects due to prefixing the declaration with a ! or + or ~ operator; they are totally harmless.

In summary, anything that turns the function declaration into an expression, followed by () will immediately execute the function. This explains why all the above hacks work equally well. You can invent your own variety because coming up with an expression is not too hard.

A function declaration is simply a declaration of a function which can be executed later by calling its name followed by two brackets (). These brackets optionally contain arguments.

new function()
Just in case you haven't seen enough ways to build an immediate function here is yet another option. You can use new function () to wrap your code and execute it immediately. It works like the immediate functions described earlier and it also creates a closure. An important difference is that there is no way to pass in arguments, which in many situations is a serious disadvantage. Here is how you'd use it:

new function () {
    // code goes here
};

You can confirm that it executes immediately by including an alert:

new function () {
    alert("In 'new function ()'");
};
Run

The same new function () construct can also be used to create a new object instance, like so:

var person = new function () {
    this.age = 0;
    this.setAge = function (age) {
        this.age = age;
    };
};

This is valid JavaScript and you are using a function expression as if it were a constructor function. The only difference is that it is not really reusable. When running the above code through JSLint you will get a message that states that the first line is a "weird construction" and suggests removing the new keyword. Given all these issues we think it is better not to use this construct.

Leading semicolon
When exploring 3rd party source code, you may run into a JavaScript source file that starts with a semicolon. Typically this is used with the Module pattern by plugin developers that know that their code will be surrounded by other developer's code. It looks like this:

;(function () {
  // code goes here..
})();

Its purpose is to protect itself from preceding code that was improperly closed which can cause problems. A semicolon will prevent this from happening. If the preceding code was improperly closed then your semicolon will correct this. If it was properly closed then your semicolon will be harmless and there will be no side effects. This idiom is referred to as a leading semicolon.