Easy little steps towards better Code Quality

Computers are smart enough to understand your code but it’s the humans who require more clarity

Divyanshu Bhatnagar
Hackers @ AdPushup

--

Photo by Tim van der Kuip on Unsplash

As a developer, the code we write is most likely to be re-visited by other developers (including us) from time to time. This makes us responsible for writing a good-quality code that not only does the job efficiently but actually is easy to follow and understand.

The code should be self-explanatory and flexible for changes. Other developers should be able to understand the intent and logic behind the code without burning a lot of time. A poorly written code can make other developers go back and forth without being able to get the gist of it. This quickly becomes a challenge when you are working in a fast-paced environment and begins deterioration of code quality.

Whenever I write code, I always put in extra efforts to make it more easy to read and understand. It is the intent that matters followed by your knowledge. After having reviewed multiple pull requests, I realised that there are a few steps which are tiny but can be good initial steps towards a better code quality.

The tips below might be more specific to JavaScript but it should not stop you from understanding the intent behind using them

Order of if-else statements

Needless to say, if-else is one of the basic building blocks of our applications. Almost every module we write uses the if-else logic.

Usually, the length of code in the if and else blocks differs. In the extreme cases, one of them might end up having 2x or more lines of code than the other block.

In such scenarios, writing the smaller conditional block in the beginning saves time of the reader.

In the code snippets above, the one on the left has the larger piece of code in the first conditional block. This makes the reader go through all the code even if he’s interested in the else part. This gets worse when you have a larger piece of code.

Where as, in the right snippet, with the shorter piece of code written first, the reader can skip the rest of the code below it if that’s what he was looking for without having to scroll all the way down to find the inverse condition.

In some cases you may also skip the else part if you’re throwing/returning from the first block. The snippet on the right is a good example where we can skip the else part as we’re throwing an error in the if block.

Accessing a property for loop’s condition in for loop

Let’s suppose you have an array of users with length ≥ 1000 and you want to traverse through all the users to do some processing. Using the users.length as the conditional check for for loop makes the processor take an extra step of accessing the value of the length property after each iteration.

Avoiding property access for conditional check in loops

We can simply pull out this value in a variable and use it as the conditional. This is just a direction to think about when looping over larger data sets.

Over engineering is not a very desirable output but it should not keep you from writing better code either. You must maintain a good balance and should not leave such opportunities unattended if you know there’s a better way of doing it.

Using Math.min() and Math.max() for comparisons

There are times when we need to compare some values and return the one that matches our desired condition. Many such cases are suitable for using Math.min() and Math.max()

Notice the calculation forlargerWidth and largerHeight using ternary operator below

Using ternary operator to find the greater value

Using Math.max() instead of ternary operator makes the code more readable and short. Not only it improves the readability but also declares the intent of the logic.

Using Math.max() to find the greater value

Using setTimeout() instead of setInterval()

The setTimeout and setInterval APIs provided to us are very useful. setTimeout executes the given callback once after the given time and setInterval keeps on executing the given callback at the given interval.

Depending on the use case, we may want to run a callback function repeatedly once the previous function call is done. This is not guaranteed by the setInterval API. It will blindly run the given callback function after every x ms given to it (with some expected delay).

To solve this problem, we can use the setTimeout API and call the function repeatedly with setTimeout().

In the above example, we schedule the first call to callApiRepeatedly() with the setTimeout function and then schedule the subsequent calls from inside the callApiRepeatedly() function. This ensures that no two executions of callApiRepeatedly will coexist. This is not guaranteed by the setInterval function as it will keep executing the callApiRepeatedly() function at the given interval irrespective of the previous call’s completion status.

Default Parameters

Default parameters were introduced in ES6 and have become friends with our code very quickly. They give us the flexibility to set a default value if no value is passed for a parameter. This, however, sometimes creates confusion. The default parameters are only used if there is no argument passed, basically the argument is undefined. Expecting them to work with falsy values should be avoided.

Another great feature of default params is that we can access the params that are defined in the order before. The example below demonstrates this.

Checking existence of a key in object

Many times we want to check if a key exists in the object or not. While there are multiple ways of achieving this, sometimes developers tend to fall into the trap of checking the existence like myObject[key] which is not the correct way of checking.

Let’s see how we can perform this operation using the in operator and Object.prototype.hasOwnProperty function, basis our requirements.

One Bonus point to note here! We could also do foo.hasOwnProperty('qux') which would have returned true but this is not considered safe. Calling foo.hasOwnProperty('qux') triggers the JS engine to find the hasOwnProperty key in the foo object first. If the key is not found, it travels down to the prototype object and finally reaches Object.prototype.hasOwnProperty function.

If we modify the foo object and add a bogus function that always returns true, we can break the code or misuse it. This is true for almost all the prototype functions.

So, it is considered as a better practice to use the Object.prototype.hasOwnProperty. See the example below.

Although, another function has been added to the Object.prototype that eliminates all the hassle and makes it easy to achieve this, Object.hasOwn()

These were some of the suggestions that I think are too simple to use but would add to your code quality and readability. Always, try to write such a code that no matter who reads it, irrespective of his experience, should be able to understand the intention behind it.

Feel free to share your thoughts in the comments. I’d love to read them.

Connect with me on LinkedIn, Divyanshu Bhatnagar

#KeepCodingAndGrowing!

--

--

A passionate and growth-oriented Software Engineer who finds learning new things and peeking under the hood really fun :)