5 points to remember when writing JavaScript code
Points to consider when writing JavaScript code
JavaScript is dynamically typed language, it means in this the errors occur only in runtime. This also means that a program written in a JavaScript can compile even if it contains type errors that would otherwise prevent the script from running properly. Being a dynamically typed language, there are common problems what a developer or team can face if the points discussed in the article is not considered.
In this article, we’ll discuss some important point what every JavaScript developer should consider when writing JavaScript code. This article assumes that the reader has some experience in writing JavaScript code. Some of the points/statements are also applicable to any programming language in general. Let’s start now.
1. Write sanity checks
In a dynamically typed language, it’s important that you write sanity checks. If you directly access the object property without checking its existence then your code is going to break when your source will return unexpected input. As a rule of thumb, in a method it should make noise when it doesn’t get what it expects and let the consumers be silent if they need to be. A module developer will never know where the module will be used, so it’s not worth making the assumption that the code should silently pass.
2. Write tests to be more confident
When you write tests, you get more confidence because you just do not rely on your brain and you believe that humans can make mistakes. When the codebase grows larger and becomes unmanageable to cover all the test cases manually. Automating and writing tests are the best way to be sure that your code works as expected.
Also when you overload the complexity that there are more than two contributors, and if your codebase has 100% code coverage then by modifying or making any changes developers will know that if it’s going to break assumption of some other section of code it’ll make noise.
3. Avoid mutation
In JavaScript, if you pass an object to a method it passes its reference. And when you write a method that mutates the object then if the consumer later relies on the object(but it should not) then you might run into the hard-to-debug type of situation. Of course, there are positive sides as well of call-by-reference but it should be used carefully. When you can do something without mutating the object, prefer that over mutating the object. Consider the following example:
let a = { field1: 10, field2: { x: 10, y: 20 }};
const doSomethingWithAxis = (point) => {
// do something, then
point.x += point.y;
// do few more thing with point
};
doSomethingWithAxis(a.field2);
console.log(a.field2.x); // will print -> 30
To fix above, you can refactor the code to:
let a = { field1: 10, field2: { x: 10, y: 20 }};
const doSomethingWithAxis = (input) => {
let point = {...input};
// do something, then
point.x += point.y;
// do few more thing with point
};
doSomethingWithAxis(a.field2);
console.log(a.field2.x); // will print -> 10
4. Avoid trusting input object as it is
Let’s say you use a NoSQL database and in your model, you pass an object to insert a document without selectively choosing what properties should be written, what do you expect? It will dump the object into the database without knowledge of what is being written to the database. This is unsafe and also a waste of resource.
5. Explore new libraries or concept before adding to your code base
When you add a new library or concepts, you should first explore the downside. If you are converting your code to use async...await
from Promise
, you should know what might be the limitation. If you are using native Promise
and going to add bluebird then you must explore which one is better and then make the decision.