The following document outlines a style guide for JavaScript programs.
- Prefer ECMAScript 5.
- We don't support ECMAScript 3-only browsers, so constructs like
typeof variable === 'undefined'
can be replaced withvariable === undefined
, et al. - Open-source code should use ECMAScript 5, as distributed programs should not require flags.
- Our Node.js servers utilize some ECMAScript 6 features. Feel free to use those features in that environment, if the code is unlikely to be ported elsewhere.
- We don't support ECMAScript 3-only browsers, so constructs like
- Place
'use strict';
at the top of scripts or functions. - Don't be tricky.
- Do be explicit.
Configure your text editor to manage the following whitespace rules:
- Strip trailing whitespace.
- Use Unix linefeeds (LF).
- End files with a newline.
This helps to avoid whitespace-oriented commits and diffs. Installing an editorconfig plugin is one easy way of enabling these rules.
Use JSCS to validate the format of your code. Our formatting rules derive from Code Conventions for the JavaScript Programming Language. Your editor may offer JSCS integration, which you may find useful if you are not familiar with the style guide. You can also use our projects' Grunt or Gulp interfaces.
Use real words for identifiers.
For instance, "element" is best written as "element", not "el", "elm", "elem", or "e".
Ubiquitous acronyms such as "http" and "url" are permissible.
Capitalize only the first letter of words in identifiers.
For instance, a phrase such as "File Transfer URI", which contains a
normally-capitalized acronym, has the identifier fileTransferUri
(as opposed
to something like fileTransferURI
).
Prefer descriptiveness, then brevity. Strive for clarity; avoid ambiguity.
Functions are verbs, everything else should be nouns.
If ECMAScript 6 features are available, prefer const
. Use let
only when the
value needs to change.
const
and let
variables should be defined separately, and close to their
site of first use. var
statements should be placed at the top of a function.
Use JSHint to validate the quality of your code and check for errors.
It is highly recommended that you integrate JSHint into your editor, or switch to an editor that offers integration. Real-time error reporting can make you more productive by pointing out syntactic and logical errors before runtime.
Prefer forEach
, map
, filter
and reduce
over for
loops.
Prefer every
and some
over continue
and break
.
Prefer Object.keys(object).forEach
or a forOwn
function over for in
loops.
Because tail calls are not yet widely implemented, use while
and do
for
algorithms that might grow the call stack boundlessly.
Aggregate operations provide forms for iterating over collections that are more precise and oftentimes more useful than their procedural alternatives.
You can leverage object-oriented design patterns such as encapsulation, composition, and inheritance in JavaScript. Create functions whose instance variables represent private and protected members. From these functions, return objects with methods to access and possibly manipulate the instance variables. Create functions with extended interfaces that mutate instances of their parents to effect inheritance.
Example:
var makeMammal = function (data) {
var self = {};
self.getName = function () {
return data.name;
};
self.says = function () {
return data.saying === undefined ? '' : data.saying;
};
return self;
};
var myMammal = makeMammal({name: 'Herb'});
var makeCat = function (data) {
var self;
data.saying = data.saying === undefined ? 'meow' : data.saying;
self = makeMammal(data);
self.purr = function (n) {
var message = '',
index;
for (index = 0; index < n; index += 1) {
if (message.length > 0) {
message += '-';
}
message += 'r';
}
return message;
};
self.getName = function () {
return self.says() + ' ' + data.name +
' ' + self.says();
};
return self;
};
var myCat = makeCat({name: 'Henrietta'});
In JavaScript, the values false
, undefined
, null
and NaN
are falsy, but
so are ''
and 0
. This is unfortunate, because sometimes empty strings and
zero are "valid" values from a business perspective. Therefore, when checking
for the "existence" of a value, it is better to be explicit than to rely on
truthiness or falsiness.
Do:
var number = value === undefined ? 100 : value;
if (number !== undefined) {
// ...
}
if (string.length > 0) {
// Is it clear that we want non-empty strings.
}
Don't:
var number = value || 100; // Excludes 0.
if (number) {
// Won't execute if the value is 0.
}
if (string) {
// It's unclear whether the author wanted to check for existence or for
// empty strings.
}
It's possible to do lots of things on one line. But that can make your code complex and confusing. You should try to do just one thing per line.
Do:
value = array[index];
index += 1;
Don't:
value = array[index++];
Abstract away complex routines to make your intentions obvious.
For instance, some people use the value returned from indexOf
to test for the
existence of substrings or elements. But it would be better to abstract that
implication into a contains
function, as you probably care about existence,
not indices.
Do:
if (contains(array, 'value')) {
// ...
}
if (isInteger(value)) {
// ...
}
Don't:
if (array.indexOf('value') > -1) {
// ...
}
if (!isNaN(parseInt(value, 10))) {
// ...
}
Influenced by: