JavaScript Coding Standards

The following are some ideas to incorporate when creating your organization’s own JavaScript Coding Standards.

There will be some deviations from strict jsLint, but by following a standard, we will ensure that everyone is coding at the highest possible level. The following is based upon and borrows heavily from the creator of jsLint Douglas Crockford’s page http://javascript.crockford.com/code.html.

Indentation

Tabs should be set to 4 spaces.

Names

JavaScript allows a wide variety of characters to be used in variable names. In general, it is best to use expressive names that use upper and lower case letters, numbers and the “_”. Avoid using names that begin with “_”. Since code is often minified before being released, it is best to use longer, descriptive names as opposed to shortened or abbreviated names.

Normal functions and variables should be written in camel case. Constructor functions that must be used with the new prefix should start with a capital letter, a.k.a. Pascal case. Global variables should be in all caps.

Comments

Comments are an explicit way to let other developers know how a piece of code works. It is critical to comment your code in conjunction with using properly named variables and functions. Use block comments for function declarations using jsDocs notation to facilitate the compilation of a hyperlinked document that describes the entire application. These block comments should list the expected parameters with their types as well as the expected return types.

Variable Declarations

Always declare your variables with the var keyword inside a scope! Variables that are declared without the var keyword are assumed to be global and have a very strong possibility of creating bugs. Variables should be declared together at the beginning of a scope to avoid issues with hoisting. Note that unlike Java, JavaScript does not have block-scope; instead it has a functional scope, and so variables should be declared at the top of functional scopes. If a variable is defined deeper in a scope, it can still be declared at the beginning of the scope. Undefined variables may be listed together on a single line. Placing undefined variables on the first line of a declaration increases readability. For instance:

Correct:

var a, b, c, d,
   e = {},
   f = 3,
   g = [1, 2, 3],
   h = function () {
       ...
   };

Incorrect:

var e = {};
var f = 3;
...
var a = 1;
var b = 2;

Function Declarations

Functions should always be declared before they are used. Inner functions should follow other variable declarations within a scope so that it is clear what outer variables that function has access to.

When declaring a named function, there should be no space between the name and the parenthesis containing the arguments, however anonymous functions do have a space between the keyword function and the opening parenthesis. In both cases, there should be a space between the closing parenthesis and the opening curly brace. Anonymous functions should also have a semicolon after the closing brace, as they are just another form of variable declaration. There is no need to name a function when an anonymous function is appropriate. Named functions should be used sparingly and only when they will be called repeatedly.

Correct:

function name(myName) {
   ...
}
var anonymous = function (myName) {
   ...
};
invokingFunction(function (result) {
    ...
}, function (err) {
    ...
});

Incorrect:

function name (myName) {
   ...
}
anonymous = function(myName){
   ...
}
invokingFunction(function success(result) {
    ...
}, function error(err) {
    ...
});

Immediate Functions

Immediate functions are a useful way to assign values to a variable based on other values, or to create scoped modules with defined API’s. Immediate functions should be declared with the function wrapped in parenthesis followed by the parameters being passed into that function in their own parenthesis afterward, like so:

(function ($) {
   ...
})(jQuery);

As you can see in this example, a variable is being passed into the immediate function and given a new name. This is a useful pattern that allows the swapping of versions of various libraries.

This follows the pattern for safely calling a callback function:

(callback || $.noop)();

Use of Curly Brackets

JavaScript is a language that makes copious use of curly brackets. jsLint prefers that curly brackets be placed on the same line as the control statement, in accordance with the K & R style. JavaScript will run with the Allman style of placing opening braces on the line after the control statement, but it is a bad practice because using the Allman style on a return statement with an object literal will cause a function to return no value due to implicit end-of-lines. If curly brackets are optional in a given construction, always opt to use them.

Correct:

return {
    ...
};

Incorrect:

return
{
    ...
};

if Statement

The if class of statements should have the following form:

if (condition) {
    ...
}
if (condition) {
    ...
} else {
    ...
}
if (condition) {
    ...
} else if (condition) {
    ...
} else {
    ...
}

Note the spaces between the “if”, the “(condition)”, and the  “{“. Also note that when it is possible to use a switch statement rather than a chain of if-else-if-else statements, it is preferred because it is more efficient in most browsers.

for Statement

A for class of statements should have the following form:

for (initialization; condition; update) {
    ...
}
for (variable in object) {
    if (filter) {
        ...
    }
}

The first form should be used with arrays and with loops of a predeterminable number of iterations. The second form should be used with objects. Be aware that members that are added to the prototype of the object will be included in the enumeration. It is wise to program defensively by using the hasOwnProperty method to distinguish the true members of the object:

for (property in object) {
    if (object.hasOwnProperty(property)) {
        ...
    }
}

while Statement

A while statement should have the following form:

while (condition) {
    ...
}

do Statement

A do statement should have the following form:

do {
    ...
} while (condition);

Unlike the other compound statements, the do statement always ends with a ; (semicolon).

switch Statement

A switch statement should have the following form:

switch (expression) {
    case expression:
        ...
        break;
    default:
        ...
}

Each case is indented from the switch. jsLint will show this as an improper construction, but it is much more readable.

Each group of statements (except the default) should end with break, return, or throw. Avoid fall-through’s.

try Statement

The try class of statements should have the following form:

try {
    ...
} catch (error) {
    ...
}
try {
    ...
} catch (error) {
    ...
} finally {
    ...
}

continue Statement

Avoid use of the continue statement. It tends to obscure the control flow of the function.

with Statement

The with statement should not be used. (http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/)

{} and []

Use {} instead of new Object(). Use [] instead of new Array().

Use arrays when the member names would be sequential integers. Use objects when the member names are arbitrary strings or names. Remember that objects will not necessarily iterate in any particular order. Avoid using code that loops through objects and expects a specific order. There are many browser versions that do not correctly maintain that order!

There is an efficiency that can be gained with arrays by using “new Array()” when creating a known number of elements. If you know the number of elements to be included in an array and that number is sufficiently large (~1000+), it is much faster to declare the array using the new operator rather than the “[]”. That said, for smaller arrays or those which do not have a set number of elements, it is better to use “[]”.

, (comma) Operator

Avoid the use of the comma operator. (This does not apply to the comma separator, which is used in object literals, array literals, var statements, and parameter lists.)

Assignment Expressions

Avoid doing assignments in the condition part of if and while statements.

Is

if (a = b) {

a correct statement? Or was

if (a == b) {

intended? Avoid constructs that cannot easily be determined to be correct.

=== and !== Operators

Use the === and !== operators. The == and != operators do type coercion and should not be used. Because they are not strict comparators, they are less efficient in JavaScript engines.

+= and -= versus ++ and –

jsLint prefers the usage of += over ++ because JavaScript engines must translate ++ into += and so it is less performant.

Confusing Pluses and Minuses

Be careful to not follow a + with + or ++. This pattern can be confusing. Insert parentheses between them to make your intention clear.

total = subtotal + +myInput.value;

is better written as

total = subtotal + (+myInput.value);

so that the + + is not misread as ++.

eval is Evil

The eval function is the most misused feature of JavaScript. Avoid it.

eval has aliases. Avoid using the Function constructor. Also, do not pass strings to setTimeout or setInterval.

That said, there are many legitimate uses for eval and Function, but these are rare and, unless absolutely necessary, should be avoided.

Bitwise Operators

One of the beautiful things about JavaScript is that it is an interpreted language. It is rarely, if ever, necessary to use bitwise operators. Remember that using bitwise operators for logical evaluations will force a type onto variables and may lead to unexpected return values.

General Guidelines

All Boolean variables should start with “is”, such as “isValid”.

Blank lines are useful for blocking off sections of code that logically fit together. One can think of blank lines like the spacing between paragraphs. It is not necessary to place a blank line in between every statement.

Be sure to end your statements with semicolons, where appropriate. Avoid implied end-of-lines.

This entry posted in Uncategorized. Entry Tags: Bookmark the permalink. 

Comments are closed.