These are the Javascript-specific coding styles. Anything mentions here overrides/adds to the "In General" guides. The only 1 principle when coding Javascript is that:
_
) and dash (-
) instead of space (
)..js
only.\'
, \"
, \\
, \b
, \f
, \n
, \r
, \t
, \v
, and etc.\x0a
, \u000a
, or \u{a}
).Example:
/* BEST */
const units = 'μs';
/* BAD: what's the point? */
const units = '\u03bcs'; // 'μs'
/* WORSE: what's the point at all? You're using UTF-8. */
const units = '\u03bcs'; // Greek letter mu, 's'
/* WORST: compromising readability by making people guessing. */
const units = '\u03bcs';
/* GOOD: use escapes for non-printable characters, and comment if necessary. */
return '\ufeff' + content; // byte order mark
Example:
/** Copyright (C) Chew Kean Ho, Inc - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Chew Kean Ho <hollowaykeanho@gmail.com>, September 2018
*
* @fileOverview Custom code for the Candidates List page.
* Program flow on page load:
* - customSearchInit()
* - initSearchPage()
* - populateDropdownFields()
* - LoadAdditionalListDataAndContinue()
* - loadListData()
* - generateHtmlTable()
* - finishAsync()
* - completePageLoad()
*/
Not recommended:
if (someVeryLongCondition())
doSomething();
if (shortCondition())
return;
for (let i = 0; i < foo.length; i++) bar(foo[i]);
Recommended:
if (someVeryLongCondition()) doSomething();
if (shortCondition()) return;
for (let i = 0; i < foo.length; i++)
bar(foo[i]);
else
, catch
, while
, or a comma, semicolon, or right-parenthesis.class InnerClass {
constructor() {}
/** @param {number} foo */
method(foo) {
if (condition(foo)) {
try {
// Note: this might fail.
something();
} catch (err) {
recover();
}
}
}
}
Not Recommended:
function doNothing() {
// do nothing
}
if (condition) {
// …
} else if (otherCondition) {} else {
// …
}
try {
return handleNumericResponse(response);
} catch (ok) {}
return handleTextResponse(response);
Recommended:
function doNothing() {}
if (condition) {
// …
} else if (otherCondition) {
// do nothing
} else {
// …
}
try {
return handleNumericResponse(response);
} catch (ok) {
// it's not numeric; that's fine, just continue
}
return handleTextResponse(response);
Some examples of array:
const a = [0, 1, 2];
const b = [
0,
1,
2,
];
const c =
[0, 1, 2];
someMethod(foo, [
0, 1, 2,
], bar);
Some examples of object literals:
const a = {
a: 0,
b: 1,
};
const b =
{a: 0, b: 1};
const c = {a: 0, b: 1};
someMethod(foo, {
a: 0, b: 1,
}, bar);
DO NOT:
const a1 = new Array(x1, x2, x3);
const a2 = new Array(x1, x2);
const a3 = new Array(x1);
const a4 = new Array();
DO:
const a1 = [x1, x2, x3];
const a2 = [x1, x2];
const a3 = [x1];
const a4 = [];
class Foo {
constructor() {
/** @type {number} */
this.x = 42;
}
/** @return {number} */
method() {
return this.x;
}
}
Foo.Empty = class {};
Inheritance example:
/** @extends {Foo<string>} */
foo.Bar = class extends Foo {
/** @override */
method() {
return super.method() / 2;
}
};
/** @interface */
class Frobnicator {
/** @param {string} message */
frobnicate(message) {}
}
prefix.something.reallyLongFunctionName('whatever', (a1, a2) => {
// Indent the function body +2 relative to indentation depth
// of the 'prefix' statement one line above.
if (a1.equals(a2)) {
someOtherLongFunctionName(a1);
} else {
andNowForSomethingCompletelyDifferent(a2.parrot);
}
});
some.reallyLongFunctionCall(arg1, arg2, arg3)
.thatsWrapped()
.then((result) => {
// Indent the function body +2 relative to the indentation depth
// of the '.then()' call.
if (result) {
result.use();
}
});
// Arguments start on a new line, indented four spaces. Preferred when the
// arguments don't fit on the same line with the function name (or the keyword
// "function") but fit entirely on the second line. Works with very long
// function names, survives renaming without reindenting, low on space.
doSomething(
descriptiveArgumentOne, descriptiveArgumentTwo, descriptiveArgumentThree) {
// …
}
// If the argument list is longer, wrap at 80. Uses less vertical space,
// but violates the rectangle rule and is thus not recommended.
doSomething(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
// …
}
// Four-space, one argument per line. Works with long function names,
// survives renaming, and emphasizes each argument.
doSomething(
veryDescriptiveArgumentNumberOne,
veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy,
artichokeDescriptorAdapterIterator) {
// …
}
switch (animal) {
case Animal.BANDERSNATCH:
handleBandersnatch();
break;
case Animal.JABBERWOCK:
handleJabberwock();
break;
default:
throw new Error('Unknown animal');
}
{
tiny: 42, // this is great
longer: 435, // this too
};
{
tiny: 42, // permitted, but future edits
longer: 435, // may leave it unaligned
};
/*
* This is
* okay.
*/
// And so
// is this.
/* This is fine, too. */
someFunction(obviousParam, true /* shouldRender */, 'hello' /* name */);
const
or let
declaration./** @type integer */
let a = 2
/** @type integer */
let b = 3
/** @type {!Array<number>} */
const data = [];
const /** !Array<number> */ data = [];
ILLEGAL:
const longString = 'This is a very long string that far exceeds the 80 \
column limit. It unfortunately contains long stretches of spaces due \
to how the continued lines are indented.';
CORRECT:
const longString = 'This is a very long string that far exceeds the 80 ' +
'column limit. It does not contain long stretches of spaces since ' +
'the concatenated strings are cleaner.';
this
to refer global object.BAD:
const /** Boolean */ x = new Boolean(false);
if (x) alert(typeof x); // alerts 'object' - WAT?
DO:
const /** boolean */ x = Boolean(0);
if (!x) alert(typeof x); // alerts 'boolean', as expected
XmlHttpRequest
, not XMLHTTPRequest
newCustomerId
, not newCustomerID
innerStopwatch
, not innerStopWatch
supportsIpv6OnIos
, not supportsIPv6OnIOS
YouTubeImporter
, not YoutubeImporter
BAD:
n // Meaningless.
nErr // Ambiguous abbreviation.
nCompConns // Ambiguous abbreviation.
wgcConnections // Only your group knows what this stands for.
pcReader // Lots of things can be abbreviated "pc".
cstmrId // Deletes internal letters.
kSecondsPerDay // Do not use Hungarian notation.
my.examplecode.deepspace // bad package name
my.example_code.deep_space // bad package name
DO:
priceCountReader // No abbreviation.
numErrors // "num" is a widespread convention.
numDnsConnections // Most people know what "DNS" stands for.
my.exampleCode.deepSpace // good package name
@suppress
annotation.There are more Javascript practices but these should be suffice to keep the train going. For more information, you can read:
That's all about Javascript.