JavaScript Coding Patterns

Theekshana Wijesinghe
4 min readSep 11, 2021

JavaScript A.K.A programming language of the web is a powerful programming language. Features like functions as first-class objects, closure are first-class citizens of the language when languages like Java are struggling to provide these features.
It is true that there are some weird behaviors like [] + 0 = '0' in the language, but the focus should in the good parts of the language.

In this article, I will introduce few coding patterns using JavaScript which I find effective. One may not necessarily agree with all the patterns because a pattern is sort of a preference, and everyone's preference is different.

Early returns

Let’s look into an example of this.

function calculateTotal(priceArray) {  let price = 0;  if(!Array.isArray(priceArray) || priceArray.length === 0) 
return price; // Also possible to return an error
if(typeof priceArray[0] !== 'number') return price; priceArray.forEach((value) => {
price += value;
});
return price;}

In the function, type check is done at the beginning of the function and if the param is not of the type of Array or if it is an empty array, 0 is returned. The second check is the type check for elements in the array (This is not a sophisticated type check but it was placed there to explain this pattern) and if that fails 0 is returned. Here, the intended code is allowed to be executed only if the checks are passed. (Note that there could be more return statements depending on the complexity of the function)

In this pattern, at the beginning of a function, there are one or more conditional checks and associated return statements. The intented code will be executed if all the checks have been passed. These checks may include type checks, null checks, value checks, any business logic related checks, … etc.

Some prefer to have only one return statement in a function but I believe this is effective and more readable.

Single object parameter

function doSomething(id, name, age, address);function doSomething({ id, name, age, address }); // Preferred way

At a glance, the above two function declarations look the same. The only difference is that the second function has only one parameter passed to it. This difference can impact your code greatly. Say,

  1. If you need to pass more parameters, in the first function you will be adding more parameters to the function but in the second you will only be adding new fields to the Object which is passed as the first parameter. Let’s take a moment to remember the SonarQube which is waiting to scream at you when the parameter count passes 7.
  2. Suppose you are not expected to pass all the values to the function. Which of the below do you think is easy to work with?
doSomething(1, undefined, undefined, '123#, street');ordoSomething({ id: 1, address: '123#, street' });

&& and || Shorthand notations

These are my favorites when working with JS. With && you can set a guard or pre-condition before executing a statement and with || you can default to something if the required value is not defined.

const id = person && person.id; 
// set id to person object's id only if person is defined
const port = process.env.PORT || 5000;
// set port to 5000 if PORT is not defined in PORT

With modern JS you can remove the need for && with ? operator

const id = person?.id; 
// id will be retrieved if person is defined only, easy right!

Destruction with a default object

Check the below code,

const { id, name, age, address } = person;

If person is null/undefined we will be walking right into a Runtime exception. With a little help from the shorthand notation introduced above, we can mitigate this easily.

const { id, name, age, address } = person || {};

Please note that this is only a part of the solution, you have to make sure the places id, name, ... are being used have correct null checks to avoid Runtime exception(s).
Avoid code like this.

const const { id, name, age, address } = person || {};...const lowerCaseName = name.toLowerCase();
// if person is null, this will give an error

This pattern works with arrays as well, below is an example.

const [head, ...rest] = arr || [];

Note: You can always use an Early Return statement to break from the function when the required params are undefined.

One line Promise resolver function

This is very interesting pattern, Let’s look at an example

// code snippet - 1 let error, data;try {
data = await fetchDataOverNetwork();
} catch(err) {
error = err;
}

Now the code with one line Promise resolver function,

// code snippet - 2const [error, data] = await promiseResolver(fetchDataOverNetwork());

We do not need try/catch here. If there is an error error will contain the error object otherwise data will contain the data coming from the function fetchDataOverNetwork.

This pattern is very useful if you have many async functions executed one after another. The reason being, when an error occurred and catch block is executed we may need lot of code inside catch block to identify the source of error and do the needful.

This pattern will get rid of the need for unncessary logic inside catch block and allows you to write readable code. Interesting right!

Let’s look at promiseResolver function

const promiseResolver = (promise) => {      if (promise instanceof Promise)
return promise
.then((value) => [null, value])
.catch((error) => [error, null]);
return [null, null];}

Check this link to identify real world use cases.

Honorable mentions: IIFE

Immediately Invoked Function Expression or IIFE for short looks like this

(function() {  console.log('Hello world, I will be invoked immediately');})();

Why do we need to define a function that is executed right away? I encourage you to read this article.

IIFEs are very useful in executing functions async code.

(async function(){     const result = await fnc();// fnc returns a promise})();

And that’s all!

Share your favourie coding pattern.

--

--