Style Guidelines

Modified on 2010/05/07 23:38 by Stephen Walther — Categorized as: Uncategorized

Style Guidelines are preferred ways to structure and format JavaScript code to further enhance readability and consistency across development teams. They may be considered optional by some development teams.Where possible the guidelines have been designed to complement developer tooling, and vice-versa.

3.1 Tabs and indenting

Tab characters (\0x09) should not be used in code. All indentation should be done with 4 space characters.

3.2 Bracing

Open braces should always be at the end of the line with the statement that begins the block. Contents of the brace should be indented by 4 spaces. For example:

if (someExpression) {
    doSomething();
}
else {
    doSomethingElse();
}

This style helps to eliminate occurrences of the semi-colon bug; that is, by design JavaScript will automatically insert a semi-colon after some statements. Adding the opening brace on the same line ensures the parser understands that the statement is intended to be split over multiple lines.

When using a “switch” statement, “case” statements should be indented as follows;

switch (someExpression)  {
    case 0:
        doSomething();
        break;
    case 1:
        doSomethingElse();
        break;
}

Braces should never be considered optional in a Debug script file. Even for single statement blocks, you should always use braces. This increases code readability and maintainability.

for (var i=0; i<100; i++) { doSomething(i); }

Minifiers may choose to remove these braces for a Release script to reduce the download size. This is best done using an automated tool, allowing the Debug script to adhere to the standard (see section 3.7.3).

3.3 Quotes

As a general rule, use single quotes to delimit strings. This means HTML fragments in code can contain double quotes inside literal strings with ease. For example;

var content = '<span id="myspan">…';

Note, however, that it is preferable to avoid emitting mark-up from code as this can complicate maintenance for layout changes.

Commenting

Comments should be used to enhance the reader’s understanding of the code with respect to its intention, algorithmic overview, and/or logical flow. Comments that do not enhance this understanding should be omitted. While there are no minimum comment requirements and some routines need no commenting at all, it is a good practise to include comments reflecting the programmer’s intent and approach.

3.4.1 Documentation comments

All methods intended to be consumed by other classes (i.e. public members, see section 2.4.1) should use XML documentation comments in debug script versions. Release versions should exclude comments.

function doSomething(index) {
    /// <summary>
    /// Performs an action on the data item indicated by index.
    /// </summary>
    /// <param name="index">An index into the list of data</param>
    /// <returns>true for success, false for failure</returns>

return this._action(_data [index]); }

Consider using AjaxDoc to extract these comments and generate documentation.

3.4.2 Comment Style

The // (two slashes) style of comment tags should be preferred over the /* */ syntax in most situations. Where possible, comments should be placed above the code that they pertain to rather than beside it.

3.5 Spacing

Good use of spaces improve readability by decreasing code density, and are removed by script minifier tools (see section 3.7.3) so should not affect download size. Here are some guidelines for the use of space characters within code:

Do use a single space after a comma between function arguments.

Wrong: doSomething(myChar,0,1); Right: doSomething(myChar, 0, 1);

Do not use a space after the parenthesis and function arguments.

Wrong: doSomething ( myChar, 0, 1 )
Right: doSomething(myChar, 0, 1)

Do not use spaces between a function name and parenthesis.

Wrong: doSomething()
Right: doSomething()

Do not use spaces inside brackets.

Wrong: x = dataArray[index ];
Right: x = dataArray[index];

Do use a single space before flow control statements.

Wrong: while(x===y)
Right: while (x === y)

Do use a single space before and after comparison operators.

Wrong: if (x===y)
Right: if (x === y)

3.6 Object Constructors

Prefer using JSON syntax to create new empty arrays or objects.

Wrong: this._dataItems = new Array();
Right: this._dataItems = [];

Wrong: this._dataItem = new Object();
Right: this._dataItem = {};

In general avoid using built in object constructors (such as Number) as this results in a boxed object, which can be costly in performance.

3.7 File Organization

3.7.1 Impact of Structure on Scope

Consider wrapping sections of script in a closure to guarantee that functions are uniquely named. This eliminates the previous practice of creating long function names, including dollar signs to separate sections of the name. These function names could become truncated by tooling and therefore of limited use.

For example, the following class declaration uses a long function name to identify the "tick" method:

MyNamespace.MyClass = function MyClass () {
    this._interval = 1000;
    this._enabled;
    this._timer = null;
}

MyNamespace.MyClass.prototype = { _tick: function MyNamespace$MyClass$tick() { alert('Ticked...'); } }

MyNamespace.MyClass.registerClass('MyNamespace.MyClass');

Instead, wrap this script in a closure as follows:

(function(window) {

MyNamespace.MyClass = function MyClass () { this._interval = 1000; this._enabled; this._timer = null; }

MyNamespace.MyClass.prototype = { _tick: function tick() { alert('Ticked...'); } } MyNamespace.MyClass.registerClass('MyNamespace.MyClass');

}) (window);

The "tick" method no longer requires a long name to ensure that it is unique, yet it will be correctly reported in debug and profiling tools.

The remainder of this document assumes this approach has been used to permit short function names.

3.7.2 Naming and Structure

Source files should generally contain whole related areas of functionality, not just a single public type. This does increase the likelihood of additional source code control conflicts and merges when multiple developers are contributing, but minimizes the number of script downloads or script combines required in the application, and ensures script references are kept brief and clear.


For example, “App.UI-1.0.1.js” would contain version 1.01 of the release build for the App.UI namespace. “App.UI-1.0.1.debug.js” would contain the equivalent debug script.

Script imports using the <reference> notation should appear at the top of the file. Comments describing the contents of the file should follow, and finally the JavaScript itself.

3.7.3 Minification

Release scripts should be processed using a script minifier, to reduce the size of the download and optionally introduce some obfuscation. One such minifier is the Microsoft Ajax Minifier.

3.7.4 NotifyScriptLoaded

The call to Sys.Application.notifyScriptLoaded is deprecated, and should therefore be removed from any files that target the current toolkit version.

3.7.5 Script Loading

Ensure that JavaScript files are configured to be cacheable by the browser when possible, to optimize the responsiveness of pages that reference them.

The Script Loader included with the Ajax Control Toolkit is the preferred way to manage the downloading of scripts and their dependencies. It can download multiple scripts in parallel and ensure that prerequisite scripts are loaded in the right order.

For guidance on using the Script Loader for custom scripts and on tuning JavaScript file downloads see the patterns & practices Web Client Guidance.