1// Do
2const units = 'μs';
1// Don't
2const units = '\u03bcs'; // Greek letter mu, 's'
1// Do
2const output = '\ufeff' + content; // byte order mark
1// Don't (no idea what this is)
2const output = '\ufeff' + content;
Avoid using
default
exports, as they allow inconsistent naming during import.1// Do
2export class Foo {...}
3
4// Or
5class Foo {...}
6export { Foo };
1// Don't
2export default class Foo {...}
Empty blocks,
1// Do
2function doNothing() {}
1// Don't
2function doNothing() {
3 // ...
4}
Where to break line → a higher syntactic level,
1// Do
2const currentEstimate =
3 calc(currentEstimate + x * currentEstimate) /
4 2.0;
1// Don't
2const currentEstimate = calc(currentEstimate + x *
3 currentEstimate) / 2.0;
Horizontal alignment: discouraged.
1// Do
2{
3 tiny: 42, // this is great
4 longer: 435, // this too
5};
1// Don't
2{
3 tiny: 42, // permitted, but future edits
4 longer: 435, // may leave it unaligned
5};
Using markdown,
1// Do
2/**
3 * Computes weight based on three factors:
4 *
5 * - items sent
6 * - items received
7 * - last timestamp
8 */
1// Don't (it will appear as a single line instead)
2/**
3 * Computes weight based on three factors:
4 * items sent
5 * items received
6 * last timestamp
7 */
No line continuations,
1// Do
2const longString = 'This is a very long string that far exceeds the 80 ' +
3 'column limit. It does not contain long stretches of spaces since ' +
4 'the concatenated strings are cleaner.';
1// Don't
2const longString = 'This is a very long string that far exceeds the 80 \
3 column limit. It unfortunately contains long stretches of spaces due \
4 to how the continued lines are indented.';
Create a new array,
1// Do
2const arr = [];
1// Don't
2const arr = new Array(length);
When adding new item to an array (given
const arr = [];
),1// Do
2arr.push(1);
1// Don't
2arr[arr.length] = 1;
1// Do: leave a space
1//Don't: no space
Add an empty line before a comment. Comments should describe the purpose of the following code block.
1function checkout(goodsPrice, shipmentPrice, taxes) {
2 // Calculate the total price
3 const total = goodsPrice + shipmentPrice + taxes;
4
5 // Create and append a new paragraph to the document
6 const para = document.createElement("p");
7 para.textContent = `Total price is ${total}`;
8 document.body.appendChild(para);
9}
1// Do
2function exampleFunc(fruitBasket) {
3 console.log(fruitBasket); // ['banana', 'mango', 'orange']
4}
5
6// Or do (if it's too long)
7function exampleFunc(fruitBasket) {
8 console.log(fruitBasket);
9 // ['banana', 'mango', 'orange', 'apple', 'pear', 'durian', 'lemon']
10}
1// Don't
2function exampleFunc(fruitBasket) {
3 // Logs: ['banana', 'mango', 'orange']
4 console.log(fruitBasket);
5}
Multi-line comments
1// Do
2// Comment can be in
3// multiple lines
1/* Don't
2 Use for multiple line
3 like this */
But we use
/* */
in below case,1array.forEach((value /* , index, array */) => {
2 // …
3});
Use camelCase for function names,
1// Do
2function sayHello() {
3 console.log("Hello!");
4}
1// Don't
2function SayHello() {
3 console.log("Hello!");
4}
5
6function doIt() {
7 console.log("Hello!");
8}
Use function declaration over function expression or arrow function,
1// Do
2function sum(a, b) {
3 return a + b;
4}
1// Don't
2let sum = function (a, b) {
3 return a + b;
4};
5
6// Don't
7const x = () => {
8 // …
9};
Use arrow function in callback,
1// Do
2const array1 = [1, 2, 3, 4];
3const sum = array1.reduce((a, b) => a + b);
1// Don't
2const array1 = [1, 2, 3, 4];
3const sum = array1.reduce(function (a, b) {
4 return a + b;
5});
6
When using arrow functions, use implicit return when possible,
1// Do
2arr.map((e) => e.id);
1// Don't
2arr.map((e) => {
3 return e.id;
4});
Prefer to use
for...of
and forEach
instead of classical for (;;)
1// Do
2for (const dog of dogs) {
3 console.log(dog);
4}
5
6// or
7dogs.forEach((dog) => {
8 console.log(dog);
9});
1// Don't
2for (let i = 0; i < dogs.length; i++) {
3 console.log(dogs[i]);
4}
Use
const
in for...of
and use let
in other loops.When you need to consider index,
1// Do
2gerbils.forEach((gerbil, i) => {
3 console.log(`Gerbil #${i}: ${gerbil}`);
4});
1// Don't
2for (let i = 0; i < gerbils.length; i++) {
3 console.log(`Gerbil #${i}: ${gerbils[i]}`);
4}
Continue right after
if
, don’t use else
1// Do
2if (condition) {
3 // actions when true
4}
5// actions when false
1// Don't
2if (condition) {
3 // actions when true
4} else {
5 // actions when false
6}
Use braces for control flows and loops,
1// Do
2for (const car of storedCars) {
3 car.paint("red");
4}
1// Don't
2for (const car of storedCars) car.paint("red");
Don’t add
break
after return
in switch
1// Do
2switch (species) {
3 case "chicken":
4 return farm.shed;
5 case "horse":
6 return corral.entry;
7 default:
8 return "";
9}
1// Don't
2switch (species) {
3 case "chicken":
4 return farm.shed;
5 break;
6 case "horse":
7 return corral.entry;
8 break;
9 default:
10 return "";
11}
Use
default
as the last case, don’t use break
with it.Use brackets
{}
if you define a local variable inside each case.1switch (fruits) {
2 case "Orange": {
3 const slice = fruit.slice();
4 eat(slice);
5 break;
6 }
7 case "Apple": {
8 const core = fruit.extractCore();
9 recycle(core);
10 break;
11 }
12}
Use
try...catch
to catch error,1try {
2 console.log(getResult());
3} catch (e) {
4 console.error(e);
5}
👍 Only recoverable errors should be catch!
Use PascalCase to define a class name and camelCase for the object property, methods and instances.
Use lirerals, not constructors to create a new object,
1// Do
2const obj = {}
1// Don't
2const obj = new Object()
Use method definition syntax,
1// Do
2const obj = {
3 foo() {
4 // …
5 },
6 bar() {
7 // …
8 },
9};
1// Don't
2const obj = {
3 foo: function () {
4 // …
5 },
6 bar: function () {
7 // …
8 },
9};
Use shorthand,
1// Do
2function createObject(name, age) {
3 return { name, age };
4}
1// Don't
2function createObject(name, age) {
3 return { name: name, age: age };
4}
Don’t mix quoted and unquoted keys,
1// Do
2const { width: 42, maxWidth: 43 };
1// Don't
2const { width: 42, 'maxWidth': 43 };
Prefer to use conditional ternary operator,
1// Do
2const x = condition ? 1 : 2;
1// Don't
2let x;
3if (condition) {
4 x = 1;
5} else {
6 x = 2;
7}
Use strict equality operator,
1// Do
2name === "Thi";
3age !== 25;
1// Don't
2name == "Shilpa";
3age != 25;
Use shortcuts for boolean tests,
1// Do
2if (x)
3
4// Or
5if (!y)
1// Don't
2if (x === true)
3
4// or don't
5if (y === false)
Use optional chaining
?.
1// Do
2const name = company?.group?.team
3const firstElement = list?.[0]
1// Don't
2let name;
3if (company && company.group && company.group.team) {
4 name = company.group.team;
5}
Naming,
1// Do
2const accelerometer = ...
3const cars = ...
4const a = ...
5const currencyName = ...
6const car = ...
1// Don't
2const accmtr = ...
3const carArray = ...
4const descriptiveVariable = ...
5const currency_name = ...
6const aCar = ...
1// Do
2const playerScore = 0;
3const speed = distance / time;
1// Don't
2const thisIsaveryLONGVariableThatRecordsPlayerscore345654 = 0;
3const s = d / t;
Use
let
or const
, not var
to declare a new variable!Declare one variable per line,
1// Do
2let var1;
3let var2;
4let var3 = 1;
5let var4 = 1;
1// Don't
2let var1, var2;
3let var3 = var4 = 1;
Void implicit type coercions,
1// Do
2class Person {
3 #name;
4 #birthYear;
5
6 constructor(name, year) {
7 this.#name = String(name); // 👈
8 this.#birthYear = Number(year); // 👈
9 }
10}
1// Don't
2class Person {
3 #name;
4 #birthYear;
5
6 constructor(name, year) {
7 this.#name = "" + name; // ✋
8 this.#birthYear = +year; // ✋
9 }
10}
To be continued…