JavaScript is the language so often at the core of both front-end and back-end development, making fluency in its dialects absolutely for today’s coders. Part of the reason for this proliferation across the web is for its apparent simplicity - getting started in JavaScript can feel quick and easy and starting with the “how to’s” is a great way to go. However, once you start looking deeper there are a lot of subtleties to JavaScript that are easy to overlook. Everyone makes mistakes, but once you’ve read through this list and polished your code you won’t be making these ones.

Assuming Block-Level Scope

This is an easy mistake to make, especially for new developers because it’s true in other coding languages but JavaScript is different. Making the assumption that JavaScript creates a new scope for each code-block is a common error, and the confusion this creates leads to a lot of bugs. In JavaScript something called variable hoisting occurs, where a
variable will retain its last value even upon exiting a loop.

Support for block-level scopes is slowly making its way into JavaScript however. The let keyword introduced this function in JavaScript 1.7 and it may soon become an officially supported JavaScript keyword.

function foo(){
    if(true){
        var fruit1 = 'apple';        //exist in function scope
        const fruit2 = 'banana';     //exist in block scope
        let fruit3 = 'strawberry';   //exist in block scope

    }
    console.log(fruit1);
    console.log(fruit2);
    console.log(fruit3);
}

foo();
//result:
//apple
//error: fruit2 is not defined
//error: fruit3 is not defined

Letting Memory Leaks Sneak In

Coding to avoid memory leaks takes a proactive approach, without which memory leaks ultimately sneak into your code. This makes them an exceptionally common problem in JavaScript, not least because there are a number of ways in which they can occur. When an unnecessary global variable is created by assigning a variable a value for the first time. This global variable sits in the background, and even though a variable like this won’t use a lot of memory your browser speed will still be impacted.

Try to avoid global variables wherever possible by using local variables or use the “use strict” directive, which won’t let you invoke an undeclared variable at all.

"use strict";
x = 3.14;       // This will cause an error because x is not declared

Getting Confused About Equality

JavaScript’s rules of coercion can be incredibly convenient when working with values in a boolean context as these values will be forced into a boolean value. Unfortunately, this handy shortcut creates a few easy traps for the JavaScript coder to fall into! One common mistake is for apparently empty brackets to be deemed an object under JavaScript’s boolean rules, and despite being empty and presumptively false, determined as true.

The type coercion rules are an easy place to slip up, so we recommend using === and !== rather than == or != to avoid accidents with type coercion!

let x = 'hello' && 123;   // x === 123

Inefficient DOM Manipulation

In JavaScript adding, modifying and removing elements (manipulating the DOM) is pretty easy, but you won’t always find yourself doing it in the most efficient way unless you’re careful. You could, for example, build a code that adds elements to the DOM individually - this may work, but neglects the fact that it’s an expensive operation to add a DOM element and ultimately your code will be clunky and inefficient.

A good fix to this is to get into the habit of using document fragments when you need to add multiple DOM elements. Modifying these elements when they’re detached and then attaching them afterwards will give you better performing code.

var fragment = document.createDocumentFragment();

Failing To Leverage Prototypal Inheritance

Prototypal inheritance is still not fully understood by a vast number of JavaScript coders, and therefore they aren’t making the most of this function. Slow running code can often be solved by effectively leveraging prototypal inheritance, so it’s a key skill to perfect.

Incorporating prototypal inheritance will allow an object to inherit its name property from a prototype, saving time and speeding things up down the line.

class GuitarAmp {
    constructor({
        cabinet = 'spruce',
        distortion = '1',
        volume = '0'
    } = {}) {
        Object.assign(this, {
            cabinet,
            distortion,
            volume
        });
    }
}


class BassAmp extends GuitarAmp {
    constructor(options = {}) {
        super(options);
        this.lowCut = options.lowCut;
    }
}

Creating Incorrect References To Instance Methods

This common mistake comes as a result of allowing a method to be defined in the global scope which means a window in another browser. In this instance, the keyword this is equal to that window, rather
than the instance of the object we intended.

Getting your references to instance methods right takes work, so pay close attention to how you code these otherwise you’ll start getting the wrong outputs entirely!

var x="string object";
var y=x;

There you have the six most common mistakes developers make in JavaScript. Don’t feel bad if you’ve fallen for a few of these as they’re all easy to do. Understanding the nuances of JavaScript will help you write better code in the future.