JavaScript Must Know Practices for Beginners

JavaScript Must Know Practices for Beginners

10 Guidelines to write better JavaScript Code

In every programming language, JavaScript inclusive, debugging your code can be a tedious job often more than writing your code from scratch. While some of the practices will only help you to write clean code that is easy to debug, some of these practices will actually help to improve the performance of you your code. I have read so many articles about best practices and these are the ones that I believe they should be learnt first.

01. Consistency

This consistency practice goes in two ways, first choosing your coding style carefully and second avoiding shorthand.

Coding Style

Name identifiers in consistency way is very important, lets take a look at the code below:

let firstName = "Hash";
let last_name = 'Node'

It is important to note here the first variable name, firstName is in camel case, while the other variable last_name was styled differently by separating with underscore, inconsistency. At the same time, it is not a must to terminate each statement with semi-colon ; in JavaScript, but the code will look better to be consistent, either by omiting the ; on all statements or maintain them see the code below.

let firstName = 'Hash';
let lastName = 'Node';

Shorthand

Avoid curry braces for example in loop like the code below can work just fine for a single statement:

//show area of each squares with sides from 1 - 3
for(let side = 1; side<=3; side++)
     console.log(side ** 2);

Even though this code will execute successfully but imagine that eventually you are very likely to make the two mistakes declare the variable or add another statement :

Declare a variable

//show area of each squares with sides from 1 - 3
for(let side = 1; side<=3; side++)
     let area = side ** 2;

This code above will result in error because the variable area is considered to be outside the block of for loop, in other words you have no access to the variable side while you are in the loop.

Add another statement

//show area of each squares with sides from 1 - 3
for(let side = 1; side<=3; side++)
     console.log(side)
     console.log(side ** 2)

In the code above, first statement console.log(side) is inside the loop but not console.log(side ** 2). When using these shorthand it will be better if they are written as inline as shown below and remember not to introduce new variable as show below:

//show area of each squares with sides from 1 - 3
for(let side = 1; side<=3; side++) console.log(side);

But still the best way to write the code above is by including the curly braces:

//show area of each squares with sides from 1 - 3
for(let side = 1; side<=3; side++){
     console.log(side ** 2);
}

02. Use let and const instead of var

The key words let and const creates variables with scope limit of their block. The difference between let and const is that const value cannot be changed in other words you can not re-assign const and is required to be assigned during declaration while let is dynamic, the value can be changed at anytime and if it is declared without value the default value is undefined. Variables declared with var are global and can be re-declared withing their scope which consider the code below:

var sum = 20;
var sum = 20;

It is very important to use let because, you will not be allowed to redeclare the variable sum which is redundant instead your code will produce an error which enforces consistency by ensuring the variable is only declared once within the same block.

03. Use JavaScript as External Files

The first benefit of using external JavaScript files is that it will enable you to put them at the bottom of the page which enable them to be loaded only after the entire HTML elements are loaded. Second organizing and reusing your code is easy if the scripts are in their own files rather than adding to the content of html file. In other words this is for both performance as well code re-usability and readability. You can still place the JavaScript files in <head> tag and add defer attribute to the <script> tag it to ensure that the page loads first.

<!doctype html>
<html lang='en'>
  <head>
    <!--This script will load after the page loads -->
    <script src='mainScript.js' defer></script>
  </head>
  <body>
  </body>
</html>

Modern browsers support this defer attribute but to be 100% just place the <script> tag at the bottom of <body> tag.

04. Avoid using new when creating new object

The following code is bad performance wise and I find it a little bit verbose:

const person = new Object();
person.firstName = 'Hash';
person.lastName = 'Node';
person.fullName = function(){
  return this.firstName + " " + this.lastName;
}
const brands = new Array();
brands.push('Audi');
brands.push('Tesla');

The better way to write this code is by replacing the new Object() with {} and new Array() with [] as show bellow:

const person = {};
person.firstName = 'Hash';
person.lastName = 'Node';
person.fullName = function(){
  return this.firstName + " " + this.lastName;
}

const brands = [];
brands.push('Audi');
brands.push('Tesla');

Here is also important to note that if the properties are values are ready to be set then it is even better to write this code as:

const person = {
  firstName: 'Hash',
  lastName: 'Node',
  fullName: function(){
    return this.firstName + " " + this.lastName;
  }
}

let brands = ['Audi', 'Tesla'];

You can be even attempted to use other primitive data types for example number, string, boolean as objects as show in the code below and this only lowers your code performance:

let make = new Number();
let isSold = new Boolean();
let model = new String();

Again all these objects are better used as primitive as show in the code below:

let make = 0;
let isSold = false;
let model = '';

It does not mean that the `new' keyword is rendered useless, creating an instance of your own object from classes will require it for example:

class Person{
    constructor(firstName, lastName){
        this.firstName = firstName;
        this.lastName = lastName;
    }

    fullName = function(){
        return this.firstName + " " + this.lastName;
    }
}

const person1 = new Person('John', 'Doe'); //instance of Person  
const person2 = new Person('Jane', 'Doe'); //another instance Person

Note that making an object const does not mean that you can not change value of its properties but rather mean that it cannot be re-assigned.

05. Use === instead of ==

The == converts the matching types first, this can produce undesired outcomes sometimes:

console.log(0==''); //evaluates to true
console.log(1==true) //evaluates to true

The === is strict as it will compare both the type and value and therefore the best comparison.

console.log(0===''); //evaluates to false
console.log(1===true) //evaluates to false

Unlike if statement switch statement is always strict, it compares both type and value.

06. Beware of aware of Date() object's properties

It is very important to be aware that day of the week starts from 0 to 6 and months of the year starts from 0 to 11. And note that date of the month does not start from 0 but rather starts from 1

let birthDate = new Date(2000, 1, 5); // 5 February, 2000

If birthDate is 5 January, 2000 then it should be written as shown below:

let birthDate = new Date(2000, 0, 5); //5 January, 2000

07. Always add default case to your switch block

Apart from remembering to break every case except default, it is also necessary to end with default as shown below:

switch (new Date().getDay()) {
  case 0:
    day = "Sunday";
    break;
  case 1:
    day = "Monday";
    break;
  case 2:
    day = "Tuesday";
    break;
  case 3:
    day = "Wednesday";
    break;
  case 4:
    day = "Thursday";
    break;
  case 5:
    day = "Friday";
    break;
  case 6:
    day = "Saturday";
    break;
  default:
    day = "Unknown";
}

08. Declare variables outside the loop

The code block below executes without errors but have one performance issue to be addressed.

const frameworks = ['React', 'Angular', 'Vue', 'NextJS'];

for(let i=0; i<frameworks.length; i++){
  const target = document.querySelector('#jsFrameworks');
  target.innerHTML += frameworks[i] + '<br>'; 
}

Every iteration declares the constant target and this can be avoided by declaring target DOM element outside the loop.

const frameworks = ['React', 'Angular', 'Vue', 'NextJS'];
const target = document.querySelector("#jsFrameworks");

for(let i=0; i<frameworks.length; i++){
  target.innerHTML += frameworks[i] + '<br>'; 
}

Furthermore frameworks.length is being evaluated on each iteration, the code below proves that frameworks.length is being evaluated serveral times.

const frameworks = ['React', 'Angular', 'Vue', 'NextJS'];
const target = document.querySelector("#jsFrameworks");

for(let i=0; i<frameworks.length; i++){
  target.innerHTML += frameworks[i] + '<br>'; 
  if(i===2){
    frameworks.push('jQuery');
  }
}

frameworks.length increased by 1 from 4 to 5 and the code runs just fine, this might be of advantage only if we are sure that the length of the array might change before exiting the loop but otherwise we can improve the performance by declaring the size of the array outside the block.

const frameworks = ['React', 'Angular', 'Vue', 'NextJS'];
const target = document.querySelector('#jsFrameworks');
const length = frameworks.length;

for(let i=0; i<length; i++){
  target.innerHTML += frameworks[i] + '<br>'; 
}

Notice that using for ... of loop can be even make the solution clean.

const frameworks = ['React', 'Angular', 'Vue', 'NextJS'];
const target = document.querySelector('#jsFrameworks');

for(framework of frameworks){
  target.innerHTML += framework + '<br>'; 
}

09. Reduce number of Globals

There is always a chance that you are have multiple JavaScript files in your web page and some, if not most of them are not written by you. They are probably outsourced libraries and frameworks. It is so easy to produce for example name collisions for identifiers for both functions and variable with global scope.

let make = 2015;
let brand = 'Toyota';
let model: 'Alvis';
let releaseDate = new Date('2015-05-22');

All the four globals, make, brand, model, realeaseDate above can be reduced into one global object named car for example:

const car = {
  make: 2015,
  brand: 'Toyota',
  model: 'Alvis',
  releaseDate: new Date('2015-05-22')
}

10. Be cautious when sorting arrays

The built in function sort() simplifies your task since you do not need to write your own sorting algorithm but when sorting numbers you might expect undesired results.

//with strings
const countries = ['SA', 'Benin', 'Togo', 'USA', 'Malawi', 'China'];
countries.sort(); //  ['Benin', 'China', 'Malawi', 'SA', 'Togo', 'USA']

//with numbers
const increments = [100, 50, 25, 45, 90, 44];
increments.sort(); // [100, 25, 44, 45, 50, 90]

Do not use the array.sort() on numbers, as shown above, 100 comes first then 25 because 1 is less than 2, instead add the following function as an argument to the sort() function.

//with numbers
const increments = [100, 50, 25, 45, 90, 44];
increments.sort(function(a, b){
  return a - b;
}); 
//[25, 44, 45, 50, 90, 100]

Conclusion

There are a lot of practices that will help write clean and easy to debug as well as optimized performance but these are top of my list and we all need to get used to as soon as possible. Keep exploring more guidelines and practices.