Like any kind of apps, JavaScript apps also have to be written well.
Otherwise, we run into all kinds of issues later on.
In this article, we’ll look at some tips we should follow when writing JavaScript code.
Linter Rules and Formatting Style
We can use linters to automatically make styles consistent.
This way, there won’t be any discrepancies between different styles.
And we won’t have to point out bad formatting in code reviews.
There’s the Standard JS and Airbnb styles for example.
They all have plugins for ESLint, which is the most popular linter for JavaScript code.
Nice Async Code
We shouldn’t have async code that has too much nesting.
To avoid that, we can use promises.
Instead of writing nested async callbacks like:
asyncFunc1((err, result1) => {
asyncFunc2(result1, (err, result2) => {
asyncFunc3(result2, (err, result3) => {
console.lor(result3)
})
})
})
We write:
asyncFuncPromise1()
.then(funcPromise2)
.then(funcPromise3)
.then((result) => console.log(result))
.catch((err) => console.error(err))
We have no nesting in the 2nd example except for the callbacks.
It’s much easier to read.
We can convert existing code to promises:
const fs = require('fs')
const promisify = require('es6-promisify')
const readFile = promisify(fs.readFile)
readFile(filePath)
.then((data) => JSON.parse(data))
We used the es6-promisify
package to convert Node styles async callbacks to promises.
Write Performant Code
We can optimize the code when we need to.
Instead of focusing on micro-bencmarks, we should watch for its true impacts.
This way, we won’t waste too much time unnecessarily optimizing our code.
Use let and const
We should use let
and const
to declare our variables.
This way, we always have block scoped variables that can’t be used before it’s declared.
Falsy Variables
undefined
, null
, 0, false
, NaN
, ''
(empty string) are all falsy.
We definitely have to be aware of these since when we convert them to boolean, they’ll all be false.
Create an Object Constructor
We can create an object constructor so that we can use them as templates to create new objects.
For example, we can write:
function Person(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
const james = new Person("james", "smith");
We have a constructor with the firstName
and lastName
parameters we can use with the new
operator to create new objects.
Be Careful When Using typeof, instanceof, and constructor
We can use typeof
to check for types of various kinds of values.
It works great with primitive values and functions.
However, typeof null
returns 'object'
.
Using typeof
on non-function objects also returns 'object'
.
constructor
is a property of the prototype of an object that can be overridden by code.
instanceof
lets us check for an instance of a constructor.
The check is done all the way up the prototype chain.
We can use them by writing:
const arr = [1, 2, 3];
typeof arr;
arr instanceof Array
arr.constructor();
typeof arr
returns 'object'
arr instanceof Array
returns true
.
arr.constructor()
returns []
.
Create a Self-calling Function
We can create a self calling function by wrapping it in parentheses and calling it.
For example, we can write:
(function(){
// ...
})();
(function(a, b){
var result = a + b;
return result;
})(1, 2)
We can keep private variables in the function.
Get a Random Item from an Array
We can get a random value from an array by writing:
const items = [2, 'foo', 'bar', 1, false];
const randomItem = items[Math.floor(Math.random() * items.length)];
We generate the index by using Math.floor(Math.random() * items.length)
.
And we pass that into items
.
This way, we get the index with the array.
Conclusion
We can use linters to keep code formatting consistent.
Also, we can use various constructs to make code easier to understand.
We can also get random items from an array easily.