Skip to content

JavaScript Style Guide

Greg Parris edited this page Jul 29, 2013 · 17 revisions

This document describes the JavaScript style for the Scriptish Firefox extension.

This guide was forked from the Greasemonkey's JavaScript Style Guide.

CommonJS

For CommonJS modules use the Add-on SDK Style Guide.

Use .js instead of .jsm

Some software doesn't recognize .jsm, and the m is a useless extra character.

Whitespace

  • Indent blocks with 2 spaces. No tabs. Thus, blocks should be indented as:
if (dlmgrWindow) {
  // focus on window
  dlmgrWindow.focus();
}
else {
  // open window
  dlmgr.open(window, null);
}
  • Lines should be no longer than 80 characters.
  • When breaking statements across multiple lines, continuation lines should be indented by 4 spaces (not to align with something on the previous lines). For any "block" (function arguments, object literal contents, etc) the contents should all be on the following indented line, not following the opening brace.

Bad:

compMgr.registerFactoryLocation(CID,
                                CLASSNAME,
                                CONTRACTID,
                                fileSpec,
                                location,
                                type);

Bad:

compMgr.registerFactoryLocation(CID, CLASSNAME, CONTRACTID, fileSpec,
    location, type);

Good:

compMgr.registerFactoryLocation(
    CID, CLASSNAME, CONTRACTID, fileSpec, location, type);
  • Surround binary operators with single spaces.
  • Put a single space after keywords (if, for, etc).
  • Files should contain exactly one newline at the end.
  • Lines should have no trailing whitespace.

Symbols

  • Do not use braces or a return statement for functions, if it is not necessary.
  • Braces on if/else statements are optional, unless some part of the if..else if..else statement uses braces, in which case all parts must.
  • When continuing a single statement across a line, operators should be at the beginning of the continued line, including the dot (scope resolution). Examples:
if (stack.filename != null
    && stack.filename != gmSvcFilename
    && stack.filename.substr(0, 6) != "chrome"
) {
  // do something
}

var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
    .getService(Ci.mozIJSSubScriptLoader);

Code Style

  • Always put else if and else on it's own line, as shown in the "Whitespace" section.
  • Name inline functions, this makes it easier to debug them. Just assigning a function to a property doesn't name the function, you should do something like:
var offlineObserver = {
  observe: function OO_observe(aSubject, aTopic, aState) {
    if (aTopic == "network:offline-status-changed")
      setOfflineUI(aState == "offline");
  }
};

This helps with a number of editing and debugging tools.

Function and variable naming

  • Unless otherwise specified, use camelCasedNames.
  • Constants should be in UPPER_CASE.
  • Use InterCaps and capitalize the first letter of constructors.
  • Do not pollute the global namespace. Global (chrome window scoped) definitions should be avoided, but at least use a Scriptish_ name prefix.
  • Global state variables should be prefixed with the letter g, e.g. gFormatToolbar.
  • Arguments (parameter names) should be prefixed with the letter a.
  • Private members should start with _, e.g. _internalFunction. They should not be accessed except by the class they are a member of.
  • Event handler functions should be prefixed with the word on, in particular try to use the names onLoad, onDialogAccept, onDialogCancel, etc., where this is unambiguous.
  • Function names, local variables, and object members have no prefix.
  • Try to declare local variables as near to their use as possible; initialize every variable.
  • Only declare a variable once in each scope.

JavaScript Features

  • Make sure that your code doesn't generate any strict JavaScript warnings, such as: ** Duplicate variable declaration ** Mixing return; with return value; ** Trailing comma in JavaScript object declarations.
  • Use [value1, value2] to create a JavaScript array in preference to using new Array(value1, value2).
  • Use { member: value, ... } to create a JavaScript object; over new Object().
  • Don't compare booleans to true or false. For example, write if (ioService.offline). Compare objects to null, numbers to 0 or strings to "" if there is chance for confusion.

Suggestions

These guidelines are not hard and fast rules, but almost always a good idea. Please try to follow them.

  • Use strict mode "use strict";
  • Be very careful about assignments that are also used in a boolean context, e.g.
while (node = node.parentNode) { /* ... */ }

or

for (var i=0, item; item=array[i]; i++) { /* ... */ }

This can be a common source of subtle bugs.

  • When a switch statement's case contains a body, and intentionally falls through to the next (with no break), add a comment like // nobreak to make it clear that this is intended.
  • Don't use eval() or equivalents if there is any other possible way to accomplish the goal.
  • On setTimeout
    • Don't use setTimeout() or equivalents with string parameters (it's basically the same as using eval), only function references.
    • Comment of why setTimeout is used, when it is used.

Performance

  • Don't use forEach unless it is really useful in your use case, as it is much slower than a normal for(;;) loop.
  • Use Array.slice when copying an array as it's the quickest way.

Clone this wiki locally