Javascript tips

Enhanced conditional statements

Multiple Condition Checking For multiple condition checking we can use either indexOf() or includes() method.

/* Default Approach */
if (letter === a || value === 'A' || value === b || value === 'B' || value === c || value === 'C') 
{ 

}

indexOf()

/* Index of approach */
if ([a, 'A', 2, 'B'].indexOf(letter) >= 0) { 

}

includes()

/* includes approach */
if (['a', 'A', b, 'B'].includes(letter)) { 

}

Optional Chaining Optional chaining operator (?.) enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.

/* WITHOUT OPTIONAL CHAINING */

if(words && words.letter)
{
  console.log(words.letter.value);
}

/*OPTIONAL CHAINING */

console.log(words?.letter?.value);

Conditionally setting a variable This approach reduces if else statements.

/* Before */
let employeeType = 'Permanent/Temporary'

if (employee.preferred_empType) {
    employeeType = employee.preferred_empType;
}

/* Conditionally setting a variable */
const employeeType= employee.preferred_empType || 'Permanent/Temporary';

Comparison returns By declaring comparisons in return statement will reduces 5 to 6 lines of code of conditional statements.

/* Default Approach */

// Longhand
let data;
function checkData() {
    if (!(data === undefined)) {
        return data;
    } else {
        return 'Some error occurred';
    }
}

var userData = checkData();
console.log(userData); //output userData

// Comparison returns
let data;
function checkData() {
    return data || 'Some error occurred';
}
var userData = checkData();
console.log(userData); //output userData

Experience more clear and detailed debugging

console.table() This technique provides us to return our objects, arguments, data in a tabular form on console. Also in this we have an option to restrict number of columns.

Console.table(data); 
/* deafult console.table() */
/* data stands for object need to be printed */

console.table(data,column);
/* data stands for object need to be printed */
/* column parameter used to select a subset of columns to be display on output */

console.time() and console.timeEnd() It is used to display time took to run the code. Also this is useful with analyzing performance of pieces of our code.

console.time(); // Start the timer 

// Enter the code or function for which you need to analyze the      performance

console.timeEnd(); // Ends the timer

Enums/Dictionaries

An enum is a way to store a set of constant values as a type. Most languages have in built support for enums, but in JavaScript we have to construct them ourselves using an object.

const Color = {
  RED: 'RED',
  GREEN: 'GREEN',
  BLUE: 'BLUE',
};

let redCar = {
  make: 'Ferrari',
  model: '812',
  color: Color.RED,
};

let greenCar = {
  make: 'Aston Martin',
  model: 'Vantage',
  color: Color.GREEN, 
};

Enums pair nicely with switch statements for flow control:

function getHexColor(car) {
  switch (car.color) {
    case Color.RED:
      return '#ff0000';
    case Color.GREEN:
      return '#00ff00';
    case Color.BLUE:
      return '#0000ff';
  }
}

However, sometimes this can be a bit verbose. Instead of using a switch statement here, we could use a dictionary. Dictionaries in JavaScript are declared in a very similar way to enums, but conceptually the have a different purpose. Where enums are a set of constant values, dictionaries are a collection of key/value pairs.

function getHexColor(car) {
  let hexColors= {
    [Color.RED]: '#ff0000',
    [Color.GREEN]: '#00ff00',
    [Color.BLUE]: '#0000ff',
  };

  return hexColors[car.color];
}

In the above example, we have got rid of the need for a switch statement, as we have created a dictionary with the enum values as the key, and the hex colors as the values. By removing all the clutter of the switch statement, I believe that this leads to much easier to read code.

Delete vs Splice

Use splice instead of using delete to remove an item from an array. Using delete will remove the object property, but will not reindex the array or update its length. This makes it appears as if it is undefined.

Don’t forget "var"

When you assign a variable’s value for the first time, always make sure you're not doing it to an undeclared variable. Assignment to an undeclared variable automatically results in a global variable being created. Avoid global variables ❌ Global variables are easily overwritten by other scripts. For example, if two separate parts of an application define global variables with the same name but with different purposes, it can result in unpredicted errors and it will be a horrible experience to debug such a problem. Generally, you should try to scope your code so that you need as little as possible in the global scope. The more global variables you use in your script, the less is the chance that you can use it alongside another script. Normally variables in a function should be local so that they go away when you exit the function.


"By reducing your global footprint to a single name, you significantly reduce the chance of bad interactions with other applications, widgets, or libraries." - Douglas Crockford

Always Use Semicolons

The use of semi-colons for line termination is a good practice. You won’t be warned if you forget it, because in most cases it will be inserted by the JavaScript parser but relying on Automatic Semicolon Insertion(ASI) is not encouraged. This is even included in Google’s, Airbnb’s, and jQuery’s Javascript style guides. To know about what could happen if we rely too much on ASI, checkout the 4th issue of my newsletter I shared some months back. In the last section, I have explained it with an example.

Use Numeric Separators

This is one of the most used operators when I have to deal with large numbers. When using a separator (with just an _) in number it looks better than an unseparated number. For example:

let number = 98234567

to ⬇

let number = 98_234_567

And it works for any other numeric base as well:

const binary = 0b1000_0101;
const hex = 0x12_34_56_78;

Few caveats :

  • More than one underscore in a row is not allowed let num= 100__00
  • Can not be used after leading 0 let num= 0_1
  • Not allowed at the end of numeric literals let num= 100_

map vs for loop

Use the map() function method to loop through an array’s items

var squares = [1,2,3,4].map(function (val) {  
    return val * val;  
}); 

// squares will be equal to [1, 4, 9, 16]

Immutability — The original array will be unaffected. This has potential benefits in cases where the original array is still needed elsewhere. For loops can also be written so as not to update the original array, but it requires more code and updating our new array as part of our loop operation. On the other hand map() keeps this cleaner since you only have to work in one scope to still maintain immutability Cleaner code — When doing identical things, map can almost always be written with less code than for. It can be clearly written on one line sometimes whereas for requires at least two or generally three with braces included. Also, scope isolation and a reduction in the number of variables you need alongside reduced size all make code objectively cleaner.

Rounding numbers

The toFixed() method converts a number rounding to a specified number of decimals.

var pi =3.1415;
pi = pi.toFixed(2);  // pi will be equal to 3.14


NOTE :  toFixed() returns a string and not a number.

Avoid using try-catch inside a loop

The try-catch construct creates a new variable in the current scope at runtime each time the catch clause is executed where the caught exception object is assigned to a variable.

var object = ['foo', 'bar'], i;  
for (i = 0, len = object.length; i <len; i++) {  
    try {  
        // do something that throws an exception 
    }  
    catch (e) {   
        // handle exception  
    } 
}

to ⬇

var object = ['foo', 'bar'], i;  
try { 
    for (i = 0, len = object.length; i <len; i++) {  
        // do something that throws an exception 
    } 
} 
catch (e) {   
    // handle exception  
}

When an error occurs, the first one lets you continue the loop while the second one exits the loop. The first one is suited if an exception thrown by your code is not severe enough to halt your entire program.

;