Coding Standards

A Coding Standards and Style Guide for professional JavaScript development.

Following coding standards and naming conventions is an important part of developing high quality JavaScript applications. It makes the code more understandable and easy-to-maintain.



Essentials


Having coding standards and naming conventions is important. It does not matter which standard you choose, as long as there is a standard. Ideally, the source code for the entire project should look as if it was written by a single developer.

Coming up with a generally agreed upon set of coding conventions and naming standards frequently leads to heated discussions. It takes good leadership to get a team to agree on a set of rules that all developers will follow.

To help you with this process we present a style guide that shouldn’t ruffle too many feathers. It is based on general coding conventions that are used throughout the JavaScript community, including open source projects, source code libraries, programming books, and blogs. There are a couple instances where we allow for a little more flexibility and we will explain why. You can choose to ignore these.

Indentation
JavaScript code with inconsistent indentation is impossible to read. The indentation rule is very easy to remember: anything within curly braces is indented. This includes function bodies, bodies of loops (including for, do, while, for-in), as well as ifs, switches, and also object literal notation.

Each indentations level is 4 space characters deep. Do not use tabs for indentation.

function show(input) {

....var temp = 10;

....if (input === "winter" && temp < 32) {
........alert('cold');
....}

}

Line length
The maximum line length is 80 characters. If the line goes beyond that you wrap the line immediately after an operator, such as a comma, +, -, &&, ||, etc. Vertically align the next line with the items that were interrupted.

function processRequest( argument1, argument2, argument3, argument4, 
                         argument5, argument6) {
    var x = 3;
    if (argument1 > 0 && argument2 > 0 && argument3 > 0 && 
        argument4 > 0 && argument5 > 0 && argument6 > 0) {
        alert("all args are greater than zero");
    }
}

Curly braces
Curly braces are used to group a number of statements. Curly braces should always be used, even when they are optional, because it makes the code easier to update and less error prone; especially when adding a new statement. In the example below it is clear that when adding a new line to the if statement you insert it between the braces and it will work as expected.

if (true) {
    alert("yes, true");
}

Without curly braces, it would be easy to add the new line and not realize it would be outside the if statement block.

if (true) 
   alert("yes, true");
   alert("really, very true");  // outside the if body

The one exception we make to adding curly braces is when the single statement is on the same line. Usually these are very short statements. However, once you place it on the next line, braces are required. Here are two examples: an if statement and a for loop.

if (obj === null) obj = [];

for (var i = 0; i < 10; i++) increment(value, i);

The above code is clear and concise. There is no risk of accidentally adding a new statement that is not part of the body of the if or the for statement. Function bodies normally make up many statements, but sometimes they are extremely brief and in those cases you are allowed to place the braces and the body on a single line.

var Calc = function () {
    this.add = function (x,y) { return x + y; };   // single line function
    this.sub = function (x,y) { return x - y; };
    this.mul = function (x,y) { return x * y; };
    this.div = function (x,y) { return x / y; };
};

var calc = new Calc();
alert(calc.add(3,4));      // => 7
Run

Opening braces
In some languages the question of where to place the opening brace (i.e. on the same line or on the next line) is a continuous point of contention. However, for JavaScript the convention is unambiguous: you always place it on the same line.

function process() {   // opening brace on same line
    return {
        temp: 100
    };
}

The main reason for this rule is that JavaScript automatically adds closing semicolons (;) at the end of each statement that it thinks is missing. There are cases where it inserts a semicolon and by doing this it excludes the following code block if the braces are on the next line. Here is an example:

function process() {
    return
    {
        temp: 100
    };
}

The JavaScript engine changes the above code to the code below and now suddenly your process function behaves differently. This is easily avoided by moving the opening brace one line up.

function process() {
    return;                 // <= JavaScript added semicolon
    {
        temp: 100
    };
}


Object literals generally follow the same curly brace formatting:

var person = {
    first: "John",
    last: "Watson",

    fullName: function () {
        return first + " " + last;
    }
}

Similar to small function bodies, in the case of small object and array literals you are allowed to place these on a single line:

var obj = {};
var array = [];

var person = {first: "John", age: 25};
var values = [1, 4, 6, 8, 2, 2];

Similar to argument parenthesis (discussed below), when curly braces {} and square brackets [] are used on a single line then there is no space between the opening brace and the first element and the closing brace and the last element. For example, in the person assignment statement there are no spaces between '{first' and between '25}'.

White space
Consistent use of white space (the spacing used between the coding elements) adds to readability and maintainability.

Operators such as +, -, =, ==, ===, &&, || should be surrounded by a space before and a space after to make their expressions easier to read. Below are a few examples:

var customer = (person.type === "client");

var odd = number % 2 !== 0;

if (income > 12000 && status === "gold")

var found = (hasText && (length > 80));

Next, we will look at white space and parentheses. There should be no space on the inside of parentheses, that is, the opening parenthesis has no white space on the right hand side and the closing parenthesis no space on the left hand side. Here are some examples:

var hero = (person.type === "superman");

if (income > 10000 && age === 65) {};

for (var j = 0; j < length; j++) {};

return (profits - losses + (assets * 2));

The same rule applies when invoking a function: no spaces on either side:

go();

var sum = add(3, 4, 5, 6);

var josh = new Person("Josh", "Healey");

Named functions have no space between the name and the opening parenthesis and the argument list. However, anonymous functions have a space between the keyword function and the argument list. The reason for this is that without a space it may appear that the function name is 'function' which is incorrect.

function go(now) {
    // ...
}

var go = function (now) {
    // ...
}

Opening curly braces are always preceded with a space. If code follows a closing brace then add a space as well.

function go(options) {
   // ...
}

if (income > 10000) {
    //...
} else {
    //...
}

do {
    //...
} while (counter < 10);

try {
   //...
} catch(ex) {
   //...
} finally {
   //...
}

White space must also be used in the places listed below.

After the commas in a function argument list:

function (arg1, arg2, arg3, arg4) {
    // ...
}

After the commas in an array literal:

var array = [23, 48, 2, 0];

After the commas and semicolons in a for loop:

for (var int i = 0, len = array.length; i < len; i++) {
    // ...
}

After the commas and colons in an object literal:

var obj = {name: "Joe", age: 29};

Naming conventions
Choosing proper variable and function names is important for readability and general understanding of the code. Do not include $ or _ in names, except 1) when denoting a 'private' member (variable or function) by prefixing it with an _, or 2) to denote a jQuery variable by a $ prefix.

Variable names are written in camelCase in which the first letter is lowercase and the first letters of any subsequent word is uppercase. Try to make the first part of the name a noun (not a verb) which will make it easier to separate it from function names. Here are some examples:

var account;
var templateHolder = {};
var person = new Person("Joe");

Make your names as succinct and descriptive as possible. Ambiguity will confuse those that follow you working with the code. Single character names are not very descriptive but they are allowed for iterators and in situations where they hold a temporary value in a lengthy computation.

for (var i = 0; i < 100; i++) {       // iterator variables
    for (var j = 0; j < 100; j++) {
        sum += i * j;
    }
}

var t = (x + y) * fudgeFactor;        // temporary variable
var rate = t * 3.14 + (t * t);

In general the use of abbreviated variable names is discouraged. However, some commonly used and widely understood abbreviations are acceptable. Here is a list of those:

Abbreviation Meaning
f or fnfunction
cdcode
l or lenlength
ctxcontext
argargument
objobject
el or elemelement
valvalue
ididentifier
idxindex
n or numnumber
retreturn value
propproperty
attrattribute
prevprevious
errerror
dupduplicate
docdocument
winwindow
srcsource
destdestination
temptemporary value
regexregular expression

JavaScript does not have the notion of an access level for variables, such as, private, protected, and public. To indicate that a member (variable or method) is private, JavaScript developers often prefix the name with an underscore _. This indicates to clients that it is not meant to be accessed directly. Here are a couple examples.

var _self; 

function _locate(customer) {
    // ...
}

Function names are written in camelCase. Frequently they start with a verb, which separates them from variables as these mostly start with nouns. Here are some function examples:

function processCustomer(customer) {
    // ...
}

function calculateRate(amount) {
    // ...
}

function add(array) {
    // ...
}

An important convention in JavaScript is that all constructor functions start with an upper case character. This is to distinguish them from regular functions and prevents developers from forgetting to add the new keyword before calling the constructor. The problem with forgetting new is that the JavaScript does not flag the error and it causes very hard to detect bugs that may only be found by visually inspecting the code. The upper case name is an important visual cue that the keyword new is required.

function Person(name) {
    this.name = name;
}

var arthur = new Person("Arthur");

Abbreviations in function names are discouraged although some common ones are allowed. The list of acceptable abbreviations is the same as the variables names listed before. Function abbreviations you may see are:

Abbreviation Meaning
initinitialize
ctorconstructor
cbcallback

Comments
There are two types of comments: single line and multi-line. Single line comments are written with double slashes // and are mostly used as brief hints as to the purpose or inner workings on the code. They can be placed immediately above or after the line of code:

// Ensure membership dues are current and
// confirm retiree eligibility (age > 60) 
for (var i = 0; len = members.length; i < len; i++) {
    member = members[i];
    due = dues[member.payment.id];  // Note: dues are indexed by payment Id
    // ...
}

It is usually best to limit single line comments to 2 or 3 lines at most. If you need more lines, for example explaining a complicated algorithm or piece of logic, then use multiline comments. The preferred format is as follows:

/*
 * Ensure membership dues are current and 
 * confirm retiree eligibility (age > 60).
 * Also, the difference between eligible and 
 * ineligibility is determined by their age, 
 * their years of service, their net-worth,  
 * and their marital status.
 */ 
function isEligible(person) {
    // ...
}

This format includes asterisks * on each line, vertically aligned to create a clear demarcation of the comment block.

Well written comments will significantly add to the readability and maintainability of the code. So what do we mean with 'well written'? It certainly does not mean extensive or lengthy; in fact, programs that require lengthy comments are probably not written very clearly. You should try to write your code so that it self-documents and that 'reads like a story'.

You accomplish this with the organization and structure of your files and also with the naming of your objects, functions, properties, variables, and namespaces. Even when your code has been optimized for readability, there are still instances where you need to explain the purpose and/or the inner workings of your algorithms and other code sections.

Comments you write are intended for 2 audiences: 1) for yourself, for when you come back 3 months after writing it, and 2) for your teammates who have never seen your code before and who will need to quickly locate and correct a problem (bug) in your program.

Here are some guidelines for good comments. First: avoid the obvious.

// iterate over each person
for (var i = 0, len = persons.length; i < len; i++) {
    person = persons[i];
    // ...
}

As a programmer you know that a for-statement does looping. You see a persons array so that is what you are iterating over. This comment does not add any value; in fact it distracts the reader.

It is very important to update your comments when the code changes. There is nothing worse than comments that are outdated, incorrect, or invalid. Better to have no comments at all.

When a program is well structured and well written (i.e. it flows like a story), most developers will be able to relatively quickly see what is happening at a particular location in the code. After studying it for a while it may be clear what is happening, but what may not be obvious is why it is done; essentially what is the purpose.

Suppose you have an array of customers. You see that the program checks for each customer how long they have been doing business with your company and then some begin and end dates that are compared against the current date. Based on this evaluation some customer's creditworthiness is upgraded. You see what is does, but you wonder what it means. It turns out that the company is running a special during a limited period in which certain customers are given special rates. It is important that this is explained in the comments because by just looking at the code it is not obvious this is a temporary sales offer.

Furthermore, the explanation that this is a sales special is not really sufficient. The rules of the offer (i.e. the algorithm used) also need clarification. The above example is not very complex, but sometimes the rules for sales offers can get very complicated, so the logic needs to be documented.

Finally, if you need API documentation of your programs (for internal or external users) then use a tool that auto generates it from specially formatted comments in your code. The two most popular tools are YUIDoc and JSDoc-Toolkit. Both are open source and can be downloaded for free.

Before running the documentation tool you decorate all (public) functions with a multi-line comment box which follows a special syntax which including special tags that are prefixed with a @. The output is nicely formatted documentation in the form of a series of HTML pages that you then can publish. Here is an example of the comment syntax:

/**
 * Invoke a method on each item in the array
 * 
 * @param  {Array} array The array to iterate over.
 * @param  {Function} method The method to invoke.
 */ 
function invoke(array, method) {
}

Variable declarations
All variables should be declared before being used or else they end up in the global namespace. The JavaScript engine hoists (raises) all variable declarations to the top of the function in which they are declared. This can lead to hard-to-detect problems where variables are being used before they are initialized. Here is a simple example. As expected the code below displays 10 (two times);

function doSomething() {
    var index = 10;
    alert(index);  // => 10
    alert(index);  // => 10
}

doSomething();
Run


Next we move the variable declaration and initialization one line lower. This results in the index being undefined and later it is 10.

function doSomething() {
    alert(index);  // => undefined
    var index = 10;
    alert(index);  // => 10
}

doSomething();

Run


What JavaScript does it hoists the variable declaration to the top, but not the initialization. The code that actually executes looks like this:

function doSomething() {
    var index;
    alert(index);  // => undefined
    index = 10;
    alert(index);  // => 10
}

It gets even weirder when you also have a global variable named index:

var index = 9;

function doSomething() {
    alert(index);  // => undefined
    var index = 10;
    alert(index);  // => 10
}

doSomething();

Run

You would expect that the first alert would print 9 because index gets only shadowed by the local index variable in the next line. But this is not the case, again due to the hoisting that takes place the code that executes looks like this:

var index = 9;

function doSomething() {
    var index; 
    alert(index);  // => undefined
    index = 10;
    alert(index);  // => 10
}

What gets displayed in the first alert is the local index variable, not the global version.

Single var pattern
To avoid the above problems you should declare and optionally initialize all variables at the beginning of a function. This is a well-known coding pattern in JavaScript and is named the Single var pattern. A single var is used to declare all variables used in the function. Here is an example of how this is commonly done:

function func(arg1, arg2, arg3) {
    var index, textFormat,
        count = 0,
        person = new Person("Hillary");
        
     // ...
}

The issue of variable declaration is one of those issues where developers can get into heated debates. Some will argue that the above example is not structured enough: they would prefer this:

function func(arg1, arg2, arg3) {
    var count  = 0,
        person = new Person("Hillary"),
        index,
        textFormat;

    // ...

}

Each variable has its own line. The initialized variables are listed first, followed by the ones that are not initialized. Also notice how the = signs of the initializations are vertically aligned.

If these rules work for your team you should adopt these. In our own work we are a little less strict and have adopted a few exceptions to the single var pattern.

First, it may be helpful to group variable declarations with each group having its own var, like so:

(function () {
    var win = window,
        doc = document,
        nav = navigator;

    var userAgent = nav.userAgent,
        isIE = /msie/t.text(userAgent) && !win.opera,
        isFirefox = /Firefox/.text(userAgent),
        isWebKit = /AppleWebKit/.test(userAgent),
        hasTouch = doc.documentElement.ontouchstart !== "undefined";

    // ...

}());

We also allow multiple uninitialized variables on a line, like so. However, initialized variables are best kept on their own line:

function (employees) {
    var type, index, element, option,
        person = new Person("Annie"),
        employeeCount = employees.length;

    // ...
}

It turns out that the single-var pattern is rather error prone. If you accidentally terminate a line with a semicolon (a common mistake), then all subsequent variables become global which is highly undesirable.

function (employees) {
    var type,
        person = new Person("Annie");
        employeeCount = employees.length;   // global!

    // ...
}

Some JavaScript developers move the comma forward, to better see that each line has a comma.

function (employees) {
    var type
      , person = new Person("Annie")
      , employeeCount = employees.length;   

   // ...
}

A consequence of enforcing the single var rule is that iterator variables (like, i, j, k or count) also end up being declared and initialized at the beginning of the function. Here is an example:

function func(arr) {
    var count = 10,
        i = 0,
        len = arr.length;

    for (; i < len; i++) {
        // ..
    }
}

However, this does not feel right; the for-loop seems incomplete and unnatural. Our approach is to allow the var in the for statements where they are used. This way the declarations and their initialization are right there ('in your face' so to speak), close to where they are used. In summary, we prefer this:

function func(arr) {
    var count = 10;

    for (var i = 0, len = arr.length; i < len; i++) {
        // ..
    }
}

Function declarations
Just like variables, methods are hoisted and should be declared before they are used. Within a function it is best to declare functions immediately following the variable declarations.

function func(arr) {
    var count, element, status;

    // immediately declare methods
    var inner1 = function () { /* ... */ };
    var inner2 = function () { /* ... */ };

    // ...

}