Categories
JavaScript Best Practices

JavaScript Clean Code — Vertical Formatting

Spread the love

Formatting code in an easy to read way is an important part of keeping code clean. Code that isn’t formatted properly takes more brainpower to interpret and understand by humans.

In this article, we’ll look at how to format JavaScript code consistently so that they can be read easily by looking at vertical formatting.

Why do we Need to Format Code?

Code formatting is important because is all about communication. Readability is important for ourselves and other readers.

A code that is a jumbled mess prevents people from understanding the code. Other people can’t work on it without understanding the code.

Also, people reading the code also have to follow through with the cleaning up the code. We don’t want them to suffer because of bad formatting that can easily be fixed.

Vertical Formatting

The number of lines of code is should be less than 500 lines. Smaller files are easier to understand than big files. Big files take longer to read and so more time is spent reading code and than doing the actual work.

Source code is like a newspaper article. The farther down we go, the more detailed the article gets. This is the same for code. We have an introduction with declarations of variables and functions and then as we get lower, we get more implementation details of the code.

Blank Lines

Blank lines are important between different entitles. They’re especially important between functions and class definitions. Without them, everything becomes hard to read and frustrates readers.

For example, the following is hard to read:

class Foo {metho1(){}metho2(){}}
class Bar {metho1(){}metho2(){}}

However, the following is much easier:

class Foo {
  method1() {}

  method2() {}
}

class Bar {
  method1() {}

  method2() {}
}

So we should put some blank lines in our code.

It’s hard to focus on a section of code when they’re all bunched together.

Vertical Density

As we can see above, the code shouldn’t be too dense vertically. Always leave some room between groups of code.

We can group variable declarations together without blank lines and classes in their own group as follows:

let x = 1;
let y = 2;

class Foo {
  method1() {}

  method2() {}
}

class Bar {
  method1() {}

  method2() {}
}

Vertical Distance

It’s frustrating to have to jump from one function to the next and scroll up and down the page all the time to read our code. It makes everyone confused.

Also, it’s frustrating to jump through tons of files to find the original definition of something.

To prevent this, related concepts should be kept close to each other.

Variable Declarations

Variable declarations should be as close to their usage as possible so that their usage can be found quickly without scrolling around or jumping through different files.

Loop control variables should be declared within the loop statement so that readers will know right away that it’s used in the loop.

Instance Variables

Instance variables should be declared on top of the class so that we know that they can be found right away.

We can put them in the constructor so that we know that they’re there for us to use or change.

For example, the following class:

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  getPoint() {}

  setPoint() {}
}

Is clearer than the following:

class Point {
  getPoint() {}

  setPoint() {}

  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}

Since most people expect the initialization code for a class to be at the top. The constructor has the initialization code, so we should put it on top.

Dependent Functions

Functions that depend on each should be close together so that we don’t have to scroll through a file to find the original definitions of the functions that are called.

This reduces frustration as we have everything close enough together to be on one screen.

For example, if we have a chain of calls like the following, we should keep them together:

class Foo {
  foo() {
    this.bar();
  }

  bar() {
    this.baz();
  }

  baz() {}
}

Related Code

Related code should be near each other so that we don’t have to scroll to find related concepts in our code. They may not have direct dependence, but they’re closely related enough that we need to find them together.

For example, the following class has methods that are closely related to each other:

class Assert {
  assertTrue() {}

  assertFalse() {}

  assertNotUndefined() {}
}

All 3 assert that some condition is met, so they’re related concepts, and so they should be close together.

Vertical Ordering

The function that’s called should be below a function that does the calling. This creates a nice flow from high to a low level.

The high-level concepts are important, so they should be on top, then we can look at the lower level helper functions.

So the example above also applies here:

class Foo {
  foo() {
    this.bar();
  }

  bar() {
    this.baz();
  }

  baz() {}
}

foo calls bar to do something and bar calls baz to do another thing. Together, foo is the highest level since it’s called first, and then the calls go down the chain to baz.

Conclusion

Code formatting is important. Without it, the code is a mess that’s hard to read and thus hard to maintain. We have to be proactive in cleaning up code with messy formatting.

To do this, we have to look at the vertical formatting of the code first. Each file should have thousands or more of lines. Also, blank lines are important between groups of code like functions and variable declarations.

Also, related concepts should be grouped close together to reduce the time to search for these entities together.

Instance variables should be on top so that they’re easy to find. Other variable declarations should also be close together, but they should be near where they’re going to be used to minimize scrolling.

Finally, high level code should be above lower level helper code.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *