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 markExample:
/** 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 expectedXmlHttpRequest, not XMLHTTPRequestnewCustomerId, not newCustomerIDinnerStopwatch, not innerStopWatchsupportsIpv6OnIos, not supportsIPv6OnIOSYouTubeImporter, not YoutubeImporterBAD:
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 namemy.example_code.deep_space // bad package nameDO:
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.