JavaScript Style Guide

This document defines JavaScript style conventions, which are split into essential, coding and naming conventions.

Essential Conventions

Essential conventions include generic patterns that you should adhere to in order to write readable, consistent and maintainable code.

Minimizing Globals

Variable declarations should always be done using var to not declare them as global variables. This avoids conflicts from using a variable name across different functions as well as conflicts with global variables declared by third party plugins.

Good Example

function sum(x, y) {
  var result = x + y;
  return result;
}

Bad Example

function sum(x, y) {
  // missing var declaration, implied global
  result = x + y;
  return result;
}

Using JSLint

JSLint is a quality tool that inspects code and warns about potential problems. It can be used online and can also be integrated into several development environments, so errors can be highlighted while writing code.

Before validating your code in JSLint, you should use a code beautifier to fix basic syntax errors (like indentation) automatically. There are a number of beautifiers available online. The following ones seem to work best:

In this project, JavaScript sources have to begin with the header:

/*jslint indent: 2, maxlen: 80, nomen: true */

which means it uses two spaces indentation, 80 maximum characters per line and allows variable names starting with ‘_’. Other JSLint options can be added in sub functions if necessary.

Some allowed options are:

  • ass: true if assignment should be allowed outside of statement position.
  • bitwise: true if bitwise operators should be allowed.
  • continue: true if the continue statement should be allowed.
  • newcap: true if Initial Caps with constructor function is optional.
  • regexp: true if . and [^...] should be allowed in RegExp literals. They match more material than might be expected, allowing attackers to confuse applications. These forms should not be used when validating in secure applications.
  • unparam: true if warnings should be silenced for unused parameters.

Coding Conventions

Coding conventions include generic patterns that ensure the written code is consistently formatted.

Using two-space indentation

Tabs and 2-space indentation are being used equally. Since a lot of errors on JSLint often result from mixed use of space and tab, using 2 spaces throughout prevents these errors up front.

Good Example

function outer(a, b) {
  var c = 1,
    d = 2,
    inner;
  if (a > b) {
    inner = function () {
      return {
        "r": c - d
      };
    };
  } else {
    inner = function () {
      return {
        "r": c + d
      };
    };
  }
  return inner;
}

Bad Example

function outer(a, b) {
var c = 1,
d = 2,
inner;

if (a > b) {
inner = function () {
return {
r: c - d
}}}};

Using shorthand for conditional statements

An alternative for using braces is the shorthand notation for conditional statements. When using multiple conditions, the conditional statement can be split on multiple lines.

Good Example

// single line
var results = test === true ? alert(1) : alert(2);

// multiple lines
var results = (test === true && number === undefined ?
               alert(1) : alert(2));

var results = (test === true ?
               alert(1) : number === undefined ?
               alert(2) : alert(3));

Bad Example

// multiple conditions
var results = (test === true && number === undefined) ?
  alert(1) :
  alert(2);

Opening Brace Location

Always put the opening brace on the same line as the previous statement.

Bad Example

function func()
{
  return
  {
    "name": "Batman"
  };
}

Good Example

function func() {
  return {
    "name": "Batman"
  };
}

Closing Brace Location

The closing brace should be on the same indent level as the original function call.

Bad Example

function func() {
  return {
           "name": "Batman"
         };
}

Good Example

function func() {
  return {
    "name": "Batman"
  };
}

Variable Declaration Location

Every variables should be declared at the top of its function.

Bad Example

function first() {
  var a = 1, b = 2,
    c, d;

  // ...
}

function second() {
  var a = 1, b = 2, c;
  var d;

  // ...
}

Good Example

function third() {
  var a = 1, b = 2, c, d;

  // ...
}

function fourth() {
  var a = 1,
    b = 2,
    c,
    d;

  // ...
}

Function Declaration Location

Non anonymous functions should be declared before use and before every statements.

Bad Example

if (...) {
  return {
    "namedFunction": function namedFunction() { ... }
  };
}

// or
if (...) {
  function namedFunction() { ... }
  return {
    "namedFunction": namedFunction
  };
}

Good Example

function namedFunction() { ... }

if (...) {
  return {
    "namedFunction": namedFunction
  };
}

Anonymous Function Location

Execept if you want to keep your function without name, anonymous functions must not be declared in the same place as the variables.

Bad Example

function first() {
  var a = 1, b = 2, func = function () {
    return a;
  };
  // ...
}

Good Example

function second() {
  var a = 1, b = 2;

  function func() {
    return a;
  };
  // ...
}

You can assign a variable to an anonymous function inside non-loop statements.

Bad Example

function third() {
  var a = 1, b = 2, func;

  for (...) {
    b.forEach(function () { ... });
  }
  // ...
}

Good Example

function fourth() {
  var a = 1, b = 2, func;

  if (...) {
    func = function () { ... };
  } else {
    func = function () { ... };
  }
  // ...
}

function fifth() {
  var a = [], b = [];

  function func() { ... }

  for (...) {
    b.forEach(func);
  }
  // ...
}

Naming Conventions

Naming conventions include generic patterns for setting names and identifiers throughout a script.

Constructors

Constructor functions (called with the new statement) should always start with a capital letter:

// bad example
var test = new application();

// good example
var test = new Application();

Methods/Functions

A method/function should always start with a small letter.

// bad example
function MyFunction() {...}

// good example
function myFunction() {...}

TitleCase, camelCase

Follow the camel case convention, typing the words in lower-case, only capitalizing the first letter in each word.

// Good example constructor = TitleCase
var test = new PrototypeApplication();

// Bad example constructor
var test = new PROTOTYPEAPPLICATION();

// Good example functions/methods = camelCase
myFunction();
calculateArea();

// Bad example functions/methods
MyFunction();
CalculateArea();

Variables

Variable names with multiple words should always use an underscore between them.

// bad example
var deliveryNote = 1;

// good example
var delivery_note = 1;

Confusing variable names should end with the variable type.

// implicit type
var my_callback = doSomething();
var Person = require("./person");

// confusing names + var type
var do_something_function = doSomething.bind(context);
var value_list = getObjectOrArray();
// value_list can be an object which can be cast into an array

To use camelCase, when sometimes it is not possible to declare a function directly, the function variable name should match some pattern which shows that it is a function.

// good example
var doSomethingFunction = function () { ... };
// or
var tool = {"doSomething": function () { ... }};

// bad example
var doSomething = function () { ... };

Element Classes and IDs

JavaScript can access elements by their ID attribute and class names. When assigning IDs and class names with multiple words, these should also be separated by an underscore (same as variables).

Example

// bad example
test.setAttribute("id", "uniqueIdentifier");

// good example
test.setAttribute("id", "unique_identifier");

Discuss - checked with jQuery UI/jQuery Mobile, they don’t use written name conventions, only

  • events names should fit their purpose (pageChange for changing a page)
  • element classes use “-” like in ui-shadow
  • “ui” should not be used by third party developers
  • variables and events use lower camel-case like pageChange and activePage

Underscore Private Methods

Private methods should use a leading underscore to separate them from public methods (although this does not technically make a method private).

Good Example

var person = {
  "getName": function () {
    return this._getFirst() + " " + this._getLast();
  },
  "_getFirst": function () {
    // ...
  },
  "_getLast": function () {
    // ...
  }
};

Bad Example

var person = {
  "getName": function () {
    return this.getFirst() + " " + this.getLast();
  },
  // private function
  "getFirst": function () {
    // ...
  }
};

No Abbreviations

Abbreviations should not be used to avoid confusion.

Good Example

// delivery note
var delivery_note = 1;

Bad Example

// delivery note
var del_note = 1;

No Plurals

Plurals should not be used as variable names.

// good example
var delivery_note_list = ["one", "two"];

// bad example
var delivery_notes = ["one", "two"];

Use Comments

Comments should be used within reason but include enough information so that a reader can get a first grasp of what a part of code is supposed to do.

Good Example

var person = {
  // returns full name string
  "getName": function () {
    return this._getFirst() + " " + this._getLast();
  }
};

Bad Example

var person = {
  "getName": function () {
    return this._getFirst() + " " + this._getLast();
  }
};

Documentation

You can use YUIDoc and its custom comment tags together with Node.js to generate the documentation from the script file itself. Comments should look like this:

Good Example

/**
 * Reverse a string
 *
 * @param  {String} input_string String to reverse
 * @return {String} The reversed string
 */
function reverse(input_string) {
  // ...
  return output_string;
};

Bad Example

function reverse(input_string) {
  // ...
  return output_string;
};

Additional Readings

Resources, additional reading materials and links: