DEV Community

Cover image for Supercharge Your Skills: 7 Tips for Writing Clean and Efficient JavaScript
Sam
Sam

Posted on • Originally published at blog.dotenx.com

Supercharge Your Skills: 7 Tips for Writing Clean and Efficient JavaScript

Writing clean code is essential for every developer as it makes the code easy to read, understand and maintain. A clean code makes the life of everyone in the team easier, your code less prone to errors, and adding new features easier. In this tutorial, I'll cover 7 tips so you can write much more readable code right away.

Before we move on, remember you can build your websites on DoTenX for free. With DoTenX you can visually build the front-end or back-end of your applications easily. Use DoTenX to speed up building websites with complex databases, and integrations with other services. You can also use it to learn programming concepts 10X faster so make sure to check it out. DoTenX is also open-source and you can find the repository here: github.com/dotenx/dotenx.


Now let's start.

Use Proper Indentation

Using proper indentation not only makes it easier to read the code it also helps clarify the structure of the code. Use consistent indentation throughout your code to improve readability and make it easier to understand.

Bad style

function getTotal(items) {
  let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price;
}
  return total;
}
Enter fullscreen mode Exit fullscreen mode

Good style

function getTotal(items) {
  let total = 0;
  for (let i = 0; i < items.length; i++) {
    total += items[i].price;
  }
  return total;
}
Enter fullscreen mode Exit fullscreen mode

Use Descriptive and Meaningful Variable Names

Do yourself a favour and spend a few seconds more when you decide to add new variables especially if they're anything more than a loop counter or something like that.

Using descriptive and meaningful variable names can greatly improve the readability of your code. Also, avoid using unnecessary abbreviations as you'll definitely write code in an IDE which provides intellisence so you won't need to type in the entier variable name every time.

Bad style

let a = 'John';
let b = 'Doe';
let c = a + b;
console.log(c);
Enter fullscreen mode Exit fullscreen mode

Good style

let firstName = 'John';
let lastName = 'Doe';
let fullName = firstName + lastName;
console.log(fullName);
Enter fullscreen mode Exit fullscreen mode

Use Comments

Use comments and use them a lot. Comments are the only way you can talk to your future self in your code so be kind to yourself and explain everything worth commenting. Sometimes, it's just a constant that needs clarification, sometimes it's an entire function.

Just make sure you don't comment as you're teaching programming. Every developer should know the syntax, and the role of comments is to clarify the logic of the code.

Bad style

function movingAverage(arr, windowSize) {
  let movingAverages = [];
  for (let i = 0; i < arr.length; i++) {
    let start = i - Math.floor(windowSize / 2);
    let end = i + Math.ceil(windowSize / 2);
    if (start < 0) {
      start = 0;
    }
    if (end > arr.length) {
      end = arr.length;
    }
    let sum = 0;
    for (let j = start; j < end; j++) {
      sum += arr[j];
    }
    let avg = sum / windowSize;
    movingAverages.push(avg);
  }
  return movingAverages;
}
Enter fullscreen mode Exit fullscreen mode

Good style

function movingAverage(arr, windowSize) {
  // Initialize an array to hold the moving averages
  let movingAverages = [];

  // Loop through the array of numbers
  for (let i = 0; i < arr.length; i++) {
    // Calculate the start and end indices for the current window
    let start = i - Math.floor(windowSize / 2);
    let end = i + Math.ceil(windowSize / 2);
    // Make sure the start index is not negative
    if (start < 0) {
      start = 0;
    }
    // Make sure the end index is not past the end of the array
    if (end > arr.length) {
      end = arr.length;
    }
    // Calculate the sum of the current window of numbers
    let sum = 0;
    for (let j = start; j < end; j++) {
      sum += arr[j];
    }
    // Calculate the average of the current window of numbers
    let avg = sum / windowSize;
    // Add the average to the array of moving averages
    movingAverages.push(avg);
  }
  // Return the array of moving averages
  return movingAverages;
}
Enter fullscreen mode Exit fullscreen mode

Avoid deep nesting

It's really difficult to read and understand deeply nested code, so try to avoid it by breaking your code into smaller, more manageable chunks, or use a better way to implement the same logic.

Bad style

function getTotal(items) {
  let total = 0;
  for (let i = 0; i < items.length; i++) {
    if (items[i].category === 'clothing') {
      if (items[i].color === 'red') {
        total += items[i].price;
      }
    }
  }
  return total;
}
Enter fullscreen mode Exit fullscreen mode

Good style

function getTotal(items) {
  let total = 0;
  for (let i = 0; i < items.length; i++) {
    if (items[i].category === 'clothing' && items[i].color === 'red') {
      total += items[i].price;
    }
  }
  return total;
}
Enter fullscreen mode Exit fullscreen mode

Limit function parameters

Limit the number of parameters you pass to your functions. This tip is not about not passing the parameters the function needs to them, but it's more about how you define and organise them.

Bad style

function calculateTotal(items, taxRate, discountAmount, shippingCost, freeShippingThreshold) {
  // Do something with the parameters
}
Enter fullscreen mode Exit fullscreen mode

Good style

function calculateTotal(items, {taxRate, discountAmount, shippingCost, freeShippingThreshold}) {
  // Do something with the parameters
}
Enter fullscreen mode Exit fullscreen mode

Use smaller functions

This post is more about writing clean code and I want to avoid mixing it with concepts like SOLID principle, so look at this tip from the readability perspective.

Do not chuck everything in a single function and try to break it into smaller pieces that are easier to understand and debug.

Bad style

function processData(data) {
  let results = [];
  for (let i = 0; i < data.length; i++) {
    if (data[i].type === 'A') {
      results.push(processTypeA(data[i]));
    } else if (data[i].type === 'B') {
      results.push(processTypeB(data[i]));
    } else if (data[i].type === 'C') {
      results.push(processTypeC(data[i]));
    }
  }
  return results;
}

function processTypeA(item) {
  // Do something with item of type A
}

function processTypeB(item) {
  // Do something with item of type B
}

function processTypeC(item) {
  // Do something with item of type C
}
Enter fullscreen mode Exit fullscreen mode

Good style

function processData(data) {
  let results = [];
  for (let i = 0; i < data.length; i++) {
    results.push(processItem(data[i]));
  }
  return results;
}

function processItem(item) {
  if (item.type === 'A') {
    // Do something with item of type A
  } else if (item.type === 'B') {
    // Do something with item of type B
  } else if (item.type === 'C') {
    // Do something with item of type C
  }
}
Enter fullscreen mode Exit fullscreen mode

Use shorter lines and empty lines

Break your code into shorter lines and use empty lines to separate logical blocks, you can make your code easier to read and understand. Especially sometimes you might be tempted to use some cool tricks you find on StackOverflow or a blog to do something in a single line but usually, they just make your code less readable.

Bad style

function add(a, b) { return a + b; }
let [taxRate, discountAmount, shippingCost, freeShippingThreshold] = [99, 0, 0, 0;
Enter fullscreen mode Exit fullscreen mode

Good style

function add(a, b) {
  return a + b;
}

let taxRate = 99;
let discountAmount = 0;
let shippingCost = 0;
let freeShippingThreshold = 0;
Enter fullscreen mode Exit fullscreen mode

Top comments (16)

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

TBH, your example on comments shows how not to use comments in most situations. Almost every one of the comments is entirely unnecessary as the code is self-explanatory - as good code should be. Comments should only be used when the code does not lend itself to easy immediate understanding, or when leaving some non-obvious information there would be beneficial to someone coming to the code (maybe a link to an explanation of an algorithm used etc.)

If you were teaching a beginners course on programming your commenting style would be appropriate, but in a setting where the developers working on the code are competent with basic programming concepts, such comments would likely be viewed at best as annoying overkill, or at worst - patronising.

Collapse
 
mohsenkamrani profile image
Sam

I see your point and honestly I was thinking about this at the time of writing. Just look at it as an example to just get the idea. Not sure what could be a better example. Happy to update it if you have a better example.

Collapse
 
harishteens profile image
Harish

It took me a little more than 5 mins to understand moving average and the code. Having these comments would have cut that to less time I feel. Here is my suggestion:

/**
 * 
 * @param arr The input array
 * @param windowSize The window size for which moving average needs to be calculated
 * @returns Array of moving averages
 */
function movingAverage(arr, windowSize) {
  let movingAverages = [];
  for (let i = 0; i < arr.length; i++) {
    // start pointer positioned left by half window
    let start = Max(0, i - Math.floor(windowSize / 2));
    // end pointer positioned right by half window
    let end = Min(arr.length, i + Math.ceil(windowSize / 2));
    let sum = 0;
    // calculate sum of subarry
    for (let j = start; j < end; j++) {
      sum += arr[j];
    }
    let avg = sum / windowSize;
    movingAverages.push(avg);
  }
  return movingAverages;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jordanfrancis profile image
Jordan Francis • Edited

I agree. Comments should explain how the logic works if it’s complex, otherwise comments typically describe why.

Collapse
 
brense profile image
Rense Bakker

Excessive commenting is actually the #1 indicator of unclean code. If your code needs comments to explain it you're probably trying to do too much in one file. To give an example, this comment:

// Calculate the start and end indices for the current window
Enter fullscreen mode Exit fullscreen mode

You should probably just refactor that code into a separate function calculateWindowIndices for example.

Another bad example is redundant comments, like this:

// Loop through the array of numbers
Enter fullscreen mode Exit fullscreen mode

It does not give any more information than what the for loop on the next line already gives. Although there's one problem with that for loop... Its looping over an array called arr that's not a very descriptive name...

The rule of thumb should be: if you feel the need to add a comment to your code, consider refactoring your code to be more self-explanatory.

Collapse
 
mohsenkamrani profile image
Sam

I agree with almost every point you made, but I couldn't find a better example. Happy to update the post if you can suggest any.

Collapse
 
brense profile image
Rense Bakker

In my opinion, comments should only be used to clarify non-trivial business logic in your app. For example, I worked on an app for the concrete industry a while back and there was this sieve test logic where you'd have to calculate the modulus of the combined rest weight on all the sieves, but for sand and gravel there were different sieve seizes that we're relevant. That's something that needs additional explaining, although even in that case you can get a long way by writing functions like: getSieveSizesForSand, etc. I think I added a comment with the link to the pdf that had a detailed explanation of how the sieve testing was supposed to work.

Collapse
 
bcostaaa01 profile image
Bruno

In my point of view, you’ve missed a lot of topics in efficient and clear JavaScript…

Some other topics would include:

  • declaring variables on top of their scope, which makes it easy to see where each variable is in the current scope.
  • using strict mode.
  • using let and const instead of var. It helps avoiding a lot of errors and you can have more control over the scope of variables.
  • using arrow functions as much as possible, except on very specific cases where you can only achieve your goal with a regular function.

And this is only part of a long list of best practices for clean and efficient JavaScript code. It is not only about commenting - which in my opinion, should instead be that the code is self-explanatory, or at least as much as possible -, but also about these aspects and tools that you can make use of in order to make your JavaScript code better to read and function. As for the title of your post, I wouldn’t call it “supercharge” when it comes to skills, this is more about best practices.

Collapse
 
mohsenkamrani profile image
Sam

Thanks for your good addition. Really didn't wan to make the post longer than it is.

Collapse
 
mohsenkamrani profile image
Sam

That's a valid point, but it's not considering the context. I'm just using that function to somehow show how adding comments in certain blocks can help.

This is perhaps how I'd write it in real life but not sure if it would make more distraction rather than clarity:

/**
 * Calculates the moving average of an array of values.
 *
 * @param {number[]} array - The array of values.
 * @param {number} windowSize - The size of the moving average window.
 * @return {number[]} The array of moving averages.
 */
const movingAverage = (array, windowSize) => {
  if (array.length < windowSize) {
    return null;
  }
  return array.reduce((acc, current, index, array) => {
    if (index >= windowSize) {
      acc.push(
        array
          .slice(index - windowSize, index)
          .reduce((acc, current) => acc + current, 0) / windowSize
      );
    }
    return acc;
  }, []);
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
blindfish3 profile image
Ben Calder

These days the best approach to formatting concerns is to leave that to automated tools like Prettier: you're guaranteed consistent results that avoid unnecessary diffs in your repo.

Collapse
 
mohsenkamrani profile image
Sam

Definitely, it does a massive job in using a proper indentation, not having very long lines and other formatting issues like that.

Collapse
 
ooooo profile image
OOOOO

Thanks, it's a good practice!

Collapse
 
mohsenkamrani profile image
Sam

I'm glad you find this helpful.

Collapse
 
rabiul7772 profile image
Rabiul Akand

Information

 
mohsenkamrani profile image
Sam

Yup, fair enough.