Photo by Redaco on dribbble

Writing Clean JavaScript

Jihad Al Khurfan
Geek Culture
Published in
4 min readAug 23, 2021

--

Clean code is not just code that works, but rather code that can be easily read, reused, and refactored by others. Writing clean code is important because, in a typical work environment, you are not writing for yourself or for the machine. In reality, you are writing for a group of developers who will need to understand, edit and build over your work.

This article focuses on writing clean JavaScript code which is not framework-specific, nonetheless, most of the mentioned examples can apply to almost any other programming language. In general, the following concepts are recommendations mostly adopted from Robert C. Martin’s book Clean Code, and they are not meant to be strictly followed.

1. Variables

Use meaningful names

Names of variables should be descriptive. The rule of thumb is that most JavaScript variables are in Camel Case (camelCase).

Note that boolean names usually answer specific questions, for example:

isActive
didSubscribe
hasLinkedAccount

Avoid adding unnecessary contexts

Do not add redundant context to variable names when the context is already provided by the containing object or class.

Avoid hardcoded values

Instead of plugging in constant values, make sure to declare meaningful and searchable constants. Notice that global constants can be stylized in Screaming Snake Case (SCREAMING_SNAKE_CASE).

2. Functions

Use descriptive names

Function names can be lengthy, as long as they portray what the function actually does. Function names usually have the form of action verbs, with the possible exception of functions that return booleans — which can have the form of a “Yes or No” question. Function names should also be in Camel Case.

Use default arguments

Default arguments are cleaner than short-circuiting or using extra conditional statements inside the function body. Though, it is important here to remember that short-circuiting works for all values that are considered “falsy such as false, null, undefined, '', "", 0, and NaN, while default arguments only replace undefined.

Limit the number of arguments

As controversial as this rule might be, functions should have 0, 1, or 2 arguments. Having three arguments is already excessive, and beyond that implies either of two cases:

  • The function is already doing a lot and should be divided.
  • The data passed to the function is somehow related and can be passed as a dedicated data structure.

Avoid executing multiple actions in a function

A function should do one thing at a time. This rule helps reduce the function’s size and complexity, which results in easier testing, debugging, and refactoring. The number of lines in a function is a strong indicator that should raise a flag on whether the function is doing many actions. Generally, try aiming for something less than 20–30 lines of code.

Avoid using flags as arguments

A flag in one of the arguments effectively means the function can still be simplified.

Do not repeat yourself (DRY)

Duplicate code is never a good sign. If you repeat yourself you will have to update multiple places whenever there is a change in logic.

Avoid side effects

In JavaScript, you should favor functional over imperative patterns. In other words, keep functions pure unless needed otherwise. Side effects can modify shared states and resources, resulting in undesired behaviors. All side effects should be centralized; if you need to mutate a global value or modify a file, dedicate one and only one service for that.

Moreover, if a mutable value is passed to a function, you should return a new mutated clone of the value rather than mutating the value directly and returning it.

3. Conditionals

Use non-negative conditionals

Use shorthands whenever possible

Avoid branching and return soon

Returning early will make your code linear, more readable, and less complex.

Favor object literals or maps over switch statements

Whenever this applies, indexing using objects or maps will reduce code and improve performance.

Use optional chaining

4. Concurrency

Avoid callbacks

Callbacks are messy and result in nested code. ES6 offers Promises which allow for chaining callbacks and thus result in cleaner code. Yet, ECMAScript 2017 also provides the “Async/Await” syntax as an arguably cleaner solution that imposes further linearity to code.

5. Error Handling

Handle thrown errors and rejected promises

No need to mention why this is an extremely important rule. Spending time now on handling errors correctly will reduce the likelihood of having to hunt down bugs later, especially when your code reaches production.

6. Comments

Only comment business logic

Readable code saves you from over-commenting your code. Hence, you should only comment on complex logic.

Make use of version control

There is absolutely no reason to keep commented code or journal comments, version control is already there to handle this.

Document when possible

Documentation helps increase code quality and reliability. It serves as a user manual for your codebase in which anyone understands all the aspects of your code.

/**  
* Returns x raised to the n-th power.
*
* @param {number} x The number to raise.
* @param {number} n The power, should be a natural number.
* @return {number} x raised to the n-th power.
*/
function pow(x, n) {
// ...
}

This article discussed briefly some important steps that can be taken to increase your JavaScript code using latest syntax. Again, most of these concepts can be generalized and applied to different programming languages. Adopting these practices can take some time especially for larger codebases, but will guarantee that — for the long run — your code becomes readable, scalable, and easy to refactor.

Support me to write more!

--

--

Jihad Al Khurfan
Geek Culture

Full-Stack Software Engineer | MSE in Software Engineering