User:GavinSharp/JS Style Guidelines

  • Revision slug: User:GavinSharp//JS_Style_Guidelines
  • Revision title: User:GavinSharp/JS Style Guidelines
  • Revision id: 199849
  • Created:
  • Creator: GavinSharp
  • Is current revision? No
  • Comment /* Function and variable names */

Revision Content

Spaces, wrapping, and indentation

  • No tabs!
  • Two space indentation is standard.
  • Lines should wrap at 80 characters where possible.
  • Lines should not contain trailing spaces, even after binary operators, commas or semicolons.
  • Operators should be separated by a space
  • Do not use spaces between a function name and its arguments list, or between an array name and the square bracket. Also, do no use spaces after a bracket. Use a space after a comma to separate arguments.
fooMethod ( a1, v2 ); // bad
fooMethod(a1, v2);    // OK
  • Use a space between a keyword and parentheses.
if(condition)             // bad
if (condition)            // OK
  • Do not put compound statements in one line. Indent the controlled statement on the next line, for clarity.
if (condition) break;     // bad
if (condition)            // OK
  break;
  • Function arguments that overflow the first line of the call expression should be aligned to underhang the first argument (to start in overflow lines in the column after the opening parenthesis).
fooMethod(a1,         // bad
    v2);
fooMethod(a1,         // OK
          v2);
  • One (or two) blank lines between block definitions. Also consider breaking up large code blocks with blank lines to improve readability.
  • Keep operators at the end of the line when wrapping conditions.
  • Try to indent to line up with a related item on the previous line.
if (reallyReallyLongCondition() && someOtherLongThing()     // bad
  && somethingShorter()) {
  ...
}
if (reallyReallyLongCondition() && someOtherLongThing() &&  // OK
    somethingShorter()) {
  ...
}
var result = prompt(message, initialValue,   // bad
  caption);
var result = prompt(message, initialValue,   // OK
                    caption);
  • End each file with a newline.

Brackets

  • No brackets around single line code blocks.
  • If a statement or condition covers multiple lines, use braces for all the controlled statements (even if the else part fits on one line, brace it too).
  • Brackets should always be on the same line as "if" or "else".
if (condition)            // bad
  callThisMethod(argument1,
                 argument2);
if (condition) {          // OK
  callThisMethod(argument1,
                 argument2);
}
if (foo.bar())         // OK
  doBar();
else
  runAway();
if (foo.bar()) {       // OK
  // Comment here
  doBar();
} else {
  runAway();
}

Control flow

  • Minimize indentation using return, break, and continue where appropriate. Prefer return (break, continue) statements to cast out abnormal cases, instead of nesting "if/else" statements and indenting the common cases.
function myFunction(a) {
  if (a) {              // bad
    ...
  }
}
function myFunction(a) {
  if (!a)
    return;             // OK
  ...
}
  • If an "if" statement controls a "then" clause ending in a return statement, do not use "else" after return.
if (condition) {          // bad
  doThis();
  return;
} else
  doThat();
if (condition) {          // OK
  DoThis();
  return;
}
DoThat();
  • Avoid similar arbitrary patterns and non-sequiturs:
if (condition) {          // bad
  doThis();
  doThat();
} else {
  CleanUp();
  return;
}
DoTheOther();
if (!condition) {         // OK
  cleanUp();
  return;
}
doThis();
doThat();
doTheOther();

Function and variable names

  • Function and variable names should be interCaps, first letter lowercase.
  • All functions should have names (i.e. no anonymous functions).
  • Constants should be in UPPER_CASE.
  • Arguments (parameter names) should be prefixed with the letter a, and be as descriptive as possible.
  • 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.
  • Try to declare local variables as near to their use as possible; try to initialize every variable.

Examples:

function myFooFunction(aArg1, aArg2) {
  ...
}
var obj = {
  myFooFunction: function obj_myFooFunc(aArg1, aArg2) {
    var local = aArg1 + " foo";
    this.anotherFunction(local);
  },

  anotherFunction: function obj_anotherFunction(aArg1) {
    ...
  }
}

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
    • Undeclared variables or members. If you are unsure if an array value exists, compare the index to the array's length. If you are unsure if an object member exists, use "name" in aObject.
  • Prefer literal object notation (var obj = {}; over var obj = new Object();).
  • Similarly, with arrays, prefer var a = {{mediawiki.external('1, a, 3')}} to var a = new Array(1, a, 3);.
  • Private members should be prefixed with "_". Example:
var myObj = {
  _private: 42,
  _privFunction: function myObj__privF(aArg) {
    return aArg + 2;
  },
  pubFunction: function myObj_pubF(aArg) {
    return this._privFunction(aArg) * this._private;
  }
}
  • Getters and setters should use the get/set syntax. Example:
var myObj = {
  _myProp: 0,
  get myProp() {
    return this._myProp;
  },
  set myProp(val) {
    return this._myProp = val;
  }
}

XPCOM

  • Favor the use of Cc/Ci/Cr constants for Components.classes/Components.interfaces/Components.results
  • Periods kept at the end of the line when wrapping, indent wrapped lines to match up with space after equal sign.

Examples:

const Ci = Components.interfaces;
const Cc = Components.classes;
const Cr = Components.results;

var fooBar = Cc["@mozilla.org/foo-bar;1"].getService(Ci.nsIFooBar);

var longerFooBar = Cc["@mozilla.org/longer-foo-bar;1"].
                   getService(Ci.nsILongerFooBar);

Revision Source

<h3 name="Spaces.2C_wrapping.2C_and_indentation">Spaces, wrapping, and indentation</h3>
<ul><li>No tabs!
</li><li>Two space indentation is standard.
</li><li>Lines should wrap at 80 characters where possible.
</li><li>Lines should not contain trailing spaces, even after binary operators, commas or semicolons.
</li><li>Operators should be separated by a space
</li><li>Do not use spaces between a function name and its arguments list,                                                or between an array name and the square bracket. Also, do no use spaces after a bracket. Use a space after a comma to separate arguments.
</li></ul>
<pre class="eval">fooMethod ( a1, v2 ); // bad
fooMethod(a1, v2);    // OK
</pre>
<ul><li>Use a space between a keyword and parentheses.
</li></ul>
<pre class="eval">if(condition)             // bad
if (condition)            // OK
</pre>
<ul><li>Do not put compound statements in one line. Indent the controlled statement on the next line, for clarity.
</li></ul>
<pre class="eval">if (condition) break;     // bad
if (condition)            // OK
  break;
</pre>
<ul><li> Function arguments that overflow the first line of the call expression should be aligned to underhang the first argument (to start in overflow lines in the column after the opening parenthesis).
</li></ul>
<pre class="eval">fooMethod(a1,         // bad
    v2);
fooMethod(a1,         // OK
          v2);
</pre>
<ul><li>One (or two) blank lines between block definitions. Also consider breaking up large code blocks with blank lines to improve readability.
</li><li>Keep operators at the end of the line when wrapping conditions.
</li><li>Try to indent to line up with a related item on the previous line.
</li></ul>
<pre class="eval">if (reallyReallyLongCondition() &amp;&amp; someOtherLongThing()     // bad
  &amp;&amp; somethingShorter()) {
  ...
}
if (reallyReallyLongCondition() &amp;&amp; someOtherLongThing() &amp;&amp;  // OK
    somethingShorter()) {
  ...
}
</pre>
<pre class="eval">var result = prompt(message, initialValue,   // bad
  caption);
var result = prompt(message, initialValue,   // OK
                    caption);
</pre>
<ul><li>End each file with a newline.
</li></ul>
<h3 name="Brackets">Brackets</h3>
<ul><li>No brackets around single line code blocks.
</li><li>If a statement or condition covers multiple lines, use braces for all the controlled statements (even if the else part fits on one line, brace it too).
</li><li>Brackets should always be on the same line as "if" or "else".
</li></ul>
<pre class="eval">if (condition)            // bad
  callThisMethod(argument1,
                 argument2);
</pre>
<pre class="eval">if (condition) {          // OK
  callThisMethod(argument1,
                 argument2);
}
</pre>
<pre class="eval">if (foo.bar())         // OK
  doBar();
else
  runAway();
</pre>
<pre class="eval">if (foo.bar()) {       // OK
  // Comment here
  doBar();
} else {
  runAway();
}
</pre>
<h3 name="Control_flow">Control flow</h3>
<ul><li>Minimize indentation using return, break, and continue where appropriate.  Prefer return (break, continue) statements to cast out abnormal cases, instead of nesting "if/else" statements and indenting the common cases.
</li></ul>
<pre class="eval">function myFunction(a) {
  if (a) {              // bad
    ...
  }
}
</pre>
<pre class="eval">function myFunction(a) {
  if (!a)
    return;             // OK
  ...
}
</pre>
<ul><li>If an "if" statement controls a "then" clause ending in a return statement, do not use "else" after return.
</li></ul>
<pre class="eval">if (condition) {          // bad
  doThis();
  return;
} else
  doThat();
</pre>
<pre class="eval">if (condition) {          // OK
  DoThis();
  return;
}
DoThat();
</pre>
<ul><li> Avoid similar arbitrary patterns and non-sequiturs:
</li></ul>
<pre class="eval">if (condition) {          // bad
  doThis();
  doThat();
} else {
  CleanUp();
  return;
}
DoTheOther();
</pre>
<pre class="eval">if (!condition) {         // OK
  cleanUp();
  return;
}
doThis();
doThat();
doTheOther();
</pre>
<h3 name="Function_and_variable_names">Function and variable names</h3>
<ul><li>Function and variable names should be interCaps, first letter lowercase.
</li><li>All functions should have names (i.e. no anonymous functions).
</li><li>Constants should be in UPPER_CASE.
</li><li>Arguments (parameter names) should be prefixed with the letter a, and be as descriptive as possible.
</li><li>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.
</li><li>Try to declare local variables as near to their use as possible; try to initialize every variable.
</li></ul>
<p>Examples:
</p>
<pre>function myFooFunction(aArg1, aArg2) {
  ...
}
var obj = {
  myFooFunction: function obj_myFooFunc(aArg1, aArg2) {
    var local = aArg1 + " foo";
    this.anotherFunction(local);
  },

  anotherFunction: function obj_anotherFunction(aArg1) {
    ...
  }
}
</pre>
<h3 name="JavaScript_features">JavaScript features</h3>
<ul><li>Make sure that your code doesn't generate any strict JavaScript warnings, such as:
<ul><li>Duplicate variable declaration
</li><li>Mixing <code>return;</code> with <code>return value;</code>
</li><li>Trailing comma in JavaScript object declarations
</li><li>Undeclared variables or members.  If you are unsure if an array value exists, compare the index to the array's length. If you are unsure if an object member exists, use "name" in aObject.
</li></ul>
</li><li>Prefer literal object notation (<code>var obj = {};</code> over <code>var obj = new Object();</code>).
</li><li>Similarly, with arrays, prefer <code>var a = {{mediawiki.external('1, a, 3')}}</code> to <code>var a = new Array(1, a, 3);</code>.
</li><li>Private members should be prefixed with "_". Example:
</li></ul>
<pre>var myObj = {
  _private: 42,
  _privFunction: function myObj__privF(aArg) {
    return aArg + 2;
  },
  pubFunction: function myObj_pubF(aArg) {
    return this._privFunction(aArg) * this._private;
  }
}
</pre>
<ul><li>Getters and setters should use the get/set syntax. Example:
</li></ul>
<pre>var myObj = {
  _myProp: 0,
  get myProp() {
    return this._myProp;
  },
  set myProp(val) {
    return this._myProp = val;
  }
}
</pre>
<h3 name="XPCOM">XPCOM</h3>
<ul><li>Favor the use of Cc/Ci/Cr constants for Components.classes/Components.interfaces/Components.results
</li><li>Periods kept at the end of the line when wrapping, indent wrapped lines to match up with space after equal sign.
</li></ul>
<p>Examples:
</p>
<pre>const Ci = Components.interfaces;
const Cc = Components.classes;
const Cr = Components.results;

var fooBar = Cc["@mozilla.org/foo-bar;1"].getService(Ci.nsIFooBar);

var longerFooBar = Cc["@mozilla.org/longer-foo-bar;1"].
                   getService(Ci.nsILongerFooBar);
</pre>
Revert to this revision