DEV Community

Cover image for Clean  Code - Javascript
Swaraj Panigrahi
Swaraj Panigrahi

Posted on โ€ข Edited on

17 5

Clean Code - Javascript

It is not enough for code to work. - Robert C. Martin

Having spent hours of time writing, reviewing, and architecting web products, if there is one thing that gives me utmost satisfaction is a well-written code.

Writing clean code, to me, should not be a clichรฉ rather a table stake for any software product. During the initial days of my career, I've been fortunate(and grateful) to be mentored by developers for whom "Clean Code" was a matter of habit. As I grew up the ladder in engineering teams, I felt the necessity to document my learnings to a blog.

In this blog, I have addressed ten ideas that will help you start your journey towards writing clean maintainable code. Since I've spent the majority of my career writing code in Javascript my examples here are in Javascript. The concepts, however, can be applied to any programming language.


1. Meaningful Variable Names

// Don't do this ๐Ÿ’ฉ
const a = 3.14;`

// Do this ๐Ÿ‘Œ 
const PI = 3.14
Enter fullscreen mode Exit fullscreen mode

2. No Magic Numbers or Strings


// Don't do this ๐Ÿ’ฉ
const circumference = 2*3.14*radius;
const isAdminUser = user.type === "ADMIN";

// Do this ๐Ÿ‘Œ 
const PI = 3.14;
const USER_ROLES = {
    admin : "ADMIN",
    clerk : "CLERK"
}

const circumference = 2*PI*radius;
const isAdminUser = user.type === USER_ROLES.admin;
Enter fullscreen mode Exit fullscreen mode

Why?

  • If a magic string is being written in multiple places you have to change all of them.
  • More manual work increases chances of typos.
  • Magic numbers/Strings are not self-documenting.

3. Avoid Unwanted context

// Don't do this ๐Ÿ’ฉ
const car = {
    carMake: "BMW",
    carColor: "Black",
    carModel: "X5",
};

// Do this ๐Ÿ‘Œ 
const car = {
    make: "BMW",
    color: "Black",
    model: "X5",
};
Enter fullscreen mode Exit fullscreen mode

4. Functions should do one thing

This has to be the most important rule of software engineering. When a function does more than one thing, it is very difficult to write concise test cases for it.

// Don't do this ๐Ÿ’ฉ
function calculateAndDisplaySum(number1, number2) {
   let sum = number1 + number2;
   console.log(`Sum is ${sum}`);
}
calculateAndDisplaySum(5, 6);


// Do this ๐Ÿ‘Œ 
function calculateSum(number1, number2) {
   let sum = number1 + number2;
   return sum;
}

function displaySum(number){
   console.log(`Sum is ${number}`);
}

const sum = calculateSum(5,6);
displaySum(sum);
Enter fullscreen mode Exit fullscreen mode

5. Less than 2 arguments

When the number of arguments is less than two, it makes easier for writing effective test cases.

// Don't do this ๐Ÿ’ฉ

function createButton(name, title, disabled, onClick){
  //....
}

// Do this ๐Ÿ‘Œ 

function createButton({name, title, disabled, onClick}){
  //....
}

const addToCartBtn = createButton({
    name: "addToCart",
    title: "\"Add to Cart\","
    disabled: false,
    onClick: handleClick,
});
Enter fullscreen mode Exit fullscreen mode

6. No Booleans as function arguments

Flags tell that this function does more than one thing. Functions should do one thing(Refer #4). Split out your functions if they are following different code paths based on a boolean. This helps your code to stick to Single Responsibility Principle.

// Don't do this ๐Ÿ’ฉ
distance(pointA, pointB, true)

// Do this ๐Ÿ‘Œ 
distanceInKms(pointA, pointB);
distanceInMiles(pointA, pointB);
Enter fullscreen mode Exit fullscreen mode

7. Naming functions - Right approach

Function names should say what they do. It is a good idea to set a baseline among your development team members on how to approach this. Once this is done it is easier for anyone in the team to understand what the function is expected to do.

// This fetches data instantaneously.
const getUser = () => {};
Enter fullscreen mode Exit fullscreen mode
// This function sets data to an object.
const setUser = (user) => {};
Enter fullscreen mode Exit fullscreen mode
// This function gets data asynchronously.
const fetchUser = () => {}
Enter fullscreen mode Exit fullscreen mode
// This function helps to render DOM.
const renderUser = () => {}
Enter fullscreen mode Exit fullscreen mode
// This function helps to modify a object.
const updateUser = () => {}
Enter fullscreen mode Exit fullscreen mode
// This function helps to handle event.
const handleUserCardClick = (evt) => {}
Enter fullscreen mode Exit fullscreen mode
// These functions returns booleans to take decisions.
const shouldRenderUser = () => {}
const isAdminUser = () => {}
Enter fullscreen mode Exit fullscreen mode

8. Polymorphism over conditionals

function test (condition) {
    if (condition === "A") {
        // do something related to "A" here
    } else if (condition === "B") {
        // do something related to "B" here
    } else if (condition === "C") {
        // do something related to "C" here
    }
}

test('A');
test('B');
test('C');

// Write it this way instead

const A = {
    doTheThing: function(){
        // code related to "A" here
    }
}

const B = {
    doTheThing: function(){
        // code related to "B" here
    }
}

const C = {
    doTheThing: function(){
        //  code related to "C" here
    }
}

function test (condition) {
    condition.doTheThing();    
}

test(A);
test(B);
test(C);

Enter fullscreen mode Exit fullscreen mode

9. Use Promises, not callbacks

Javascript functions are first class citizens, but they are messy as callbacks! They are not clean and cause excessive amount of nesting.

// Don't do this ๐Ÿ’ฉ
get("https://datasource.url/endpoint"),
  (requestErr, response, body) => {
    if (requestErr) {
      console.error(requestErr);
    } else {
      writeFile("newfile.html", body, writeErr => {
        if (writeErr) {
          console.error(writeErr);
        } else {
          console.log("File written");
        }
      });
    }
  }
);

// Do this ๐Ÿ‘Œ 
get("https://datasource.url/endpoint"),
  .then(body => {
    return writeFile("newfile.html", body);
  })
  .then(() => {
    console.log("File written");
  })
  .catch(err => {
    console.error(err);
  });

Enter fullscreen mode Exit fullscreen mode

10. Comments

How much comment is too much comment? There are various schools of thoughts for this. I firmly believe in the idea of
"Good code mostly documents itself.".

I follow the principle of only commenting things that have business logic complexity.


Learning to write clean code is a journey and not a destination.

For further reading, do consider reading these books.

  1. Clean Code by Robert C Martin
  2. Clean Coder by Robert C Martin

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

๐Ÿ‘‹ Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Communityโ€”every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple โ€œthank youโ€ goes a long wayโ€”express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay