Skip to main content

Javascript - Clean code practices

· 6 min read

Sample Image

  • Writing clean code is very essential is easy to read,understand and maintain. It increases quality of a resulting product and faster resolution of bugs.

Things to keep in mind#

  • Make it work and then make it right

  • Code should be getting better with time

  • Speed is not the criteria for a developer

  • The attitude that we can go fast now and we can deal with the mess later, is bad.

  • If you are not clean, mess will slow you down within an hour

  • Requirements are urgent but architecture is important

  • A file size should not exceed 100 lines of code.

Naming#

  • A variable should be named in camelCase, so that it explains clearly what that variable is.

  • Class should be named as nouns(sometimes as verbs),

  • Functions should be named as verb,

  • Booleans should be named as a question(is, are, should, has etc.).

  • Don't be afraid of writing big names. Its good if it explains what it does clearly

  • Array- e.g fruitArr, fruits, fruitNames, fruitList

  • Boolean- prefix(is, has, have, are, should, can)e.g isUserAuthorized, areChanged, hasFruit, shouldFetchData, canDataChange

  • Numbers - e.g minDogs, totalPersons, filteredBoxLength

  • Functions- prefix(get, set, reset, fetch, remove, delete, handle, update, replace, add, insert, hide, do, mutate, trigger) e.g getUser, calculateTotal, fetchData, setInformation, updateDetails, changeAppearance, createMenu, addMonthToDate,

Functions#

  • A function body length should be in the range 1-10 lines, Shorter the function easier it is to understand.

  • A function should do only one thing.

  • use of _functionName to indicate its a utility function that is used by other public function. e.g

// myFunction is exposed to clientfunction myfunction() {  _utilFunc1()}
function _utilFunc1() {  // do something}
  • Restrict function arguments to 2, if more then pass them as object e.g
<!-- BAD -->function f1(p1, p2, p3){    /do something  }
<!-- GOOD -->function f1(paramObj){  // do something}f1({p1, p2, p3});
  • Similar finctions/concepts should be grouped together ( so that developers wont have to jump up and down)

  • Most important functions come first

  • Avoid if-else in a function based on some flag, rather create 2 separate function, same goes for switch case as well

<!-- Bad -->function createFile(name, temp) {  if (temp) {    fs.create(`./temp/${name}`);  } else {    fs.create(name);  }}
  • Separate Query from modifier : If a function is modifying an object and returning something as well, seprate this function into 2 functions, one for query and other one for modifuying an object.

  • Function callers and callees should be close: If a function calls another, keep those functions vertically close in the source file. Ideally, keep the caller right above the callee. We tend to read code from top-to-bottom, like a newspaper. Because of this, make your code read that way.

If-Else#

  • avoid negative conditions
<!-- BAD -->if(!ispresent){// do something}
<!-- GOOD -->if(isAbsent){// do something}
  • Always write linear code. If You have a group of nested conditionals and it is hard to determine the normal flow of code execution.
<!-- BAD -->public double getPayAmount() {  double result;  if (isDead){    doSomething1();  }  else {    if (isSeparated){      doSomething2();    }    else {      if (isRetired){        doSomething3();      }      else{       doSomething4();      }    }  }  return result;}<!-- GOOD -->public double getPayAmount() {  if (isDead){    return doSomething1();  }  if (isSeparated){    return doSomething2();  }  if (isRetired){    return doSomething3();  }  return doSomething4();}

Complex Conditionals#

  • When a long conditional is used in a If statement, we can extract them into a separate function or a separate const variable
<!-- BAD -->if (date && date.actual() !== 0 && (date.before(12) || date.after(9)) ) {  return 'Date is correct'}
<!-- GOOD -->
const isDateValid = date && date.actual() !== 0 && (date.before(12) || date.after(9))if(isDateValid){  return 'Date is correct'}
<!-- OR GOOD -->
function isDateValid(){  return date && date.actual() !== 0 && (date.before(12) || date.after(9))}
if(isDateValid()){  return 'Date is correct'}

Special Number#

  • Your code uses a number that has a certain meaning to it. name them in SNAKE_CASE
<!-- BAD -->potentialEnergy(mass: number, height: number): number {  return mass * height * 9.81;}
<!-- GOOD -->static const GRAVITATIONAL_CONSTANT = 9.81;
potentialEnergy(mass: number, height: number): number {  return mass * height * GRAVITATIONAL_CONSTANT;}

Comments#

  • comments should not explain code; code should explain itself

  • Avoid too much details in comments

  • Reveal intent( like rational, why some decisions were made, or why certain algo were used)

  • To caution the developer of something

  • Remove commented code, we can retrieve them in future if needed from version control

  • Only comment on complex logic or Business logic

  • Add TODO , when yun intend to do something in the future. e.g // TODO: ensure error handling is done properly

Javascript clean code tips#

  • variables decalaration
let a = 1,  b = 2
let [a, b] = [1, 2]
let a,  b = 2
  • Swapping numbers
let [a, b] = [1, 2];[a, b] = [b, a]
  • let and const : When we know that some declaration should not be changed, we should maximise use of const.
<!-- BAD -->let myfunction = ()=>{}
<!-- GOOD -->const myFunction = ()=>{}
  • Array: use of map, filter, reduce, forEach, for(let item of fruitList)

  • Destructuring object:

<!-- BAD -->const name = employee.name;const email = employee.email;const phone = employee.phone;
<!-- GOOD -->const {name, email, phone} = employee;
  • Use of promises and async and await
<!-- BAD -->function1(function (err, data) {  ...  function2(user, function (err, data) {    ...     function3(profile, function (err, data) {      ...      function4(account, function (err, data) {        ....      });    });  });});
<!-- GOOD -->function1().then(function2).then(function3).then(function2).catch((err) => console.error(err));
<!-- VERY GOOD -->async function myAsyncFunction() {try {  const data1= await function1();  const data2= await function2(data1);  const data3= await function3(data2);  return function4(data4);}catch (e) {  console.error(err);}}
  • Usageof && :
<!-- BAD -->if(data){  if(data.person){    result = data.person.name;  }}
<!-- GOOD -->result = data && data.person && data.person.name;
  • usage of || : Can be used for setting the default value;
<!-- BAD -->if(!name){  data = 'defaultName';}
<!-- GOOD -->data = name || 'defaultName';