Categories
JavaScript Best Practices

JavaScript Best Practices — Imports, Symbols, and Constructors

Spread the love

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at the proper way to import modules, the use of the Symbol constructor, and calling super before referencing this in a child class’s constructor.

No Duplicate Imports

Duplicate imports should definitely not be added. If we import multiple items from the same module, then we should put them all in one statement.

For instance, we shouldn’t write something like the following if we want to import multiple items:

import { foo } from "./module";
import { bar } from "./module";

Instead, we can save some space by writing the following:

import { foo, bar } from "./module";

The more imports we’re importing, the more space we save by consolidating all the imports into one statement if we import multiple members from the same module.

Don’t Use the Symbol as a Constructor

In JavaScript, symbols are used as unique identifiers for methods in objects and classes.

Every Symbol is unique, even if they have the same name. For instance, if we have the following code:

const foo1 = Symbol('foo');
const foo2 = Symbol('foo');
console.log(foo1 === foo2);

Then the console lot output logs false since each symbol returned by the Symbol function is their own instance.

The Symbol function isn’t a constructor. Therefore, we shouldn’t use the new operator with it.

For instance, we shouldn’t write something like the following code:

const a = new Symbol("a");

If we run that, then we’ll get the error message ‘Uncaught TypeError: Symbol is not a constructor’.

Instead, we should just call it directly as follows:

const a = Symbol("a");

The Symbol function should be called directly as a function.

Don’t Use this or super Before Calling super() in Constructors

In JavaScript, if we create a class that extends another class using the extends keyword, then we’ve to call super to call the parent class’s constructor within the child class.

If we reference this before calling super , then we would get a ReferenceError.

For instance, if we have the following classes:

class Animal {
  constructor(name) {
    this.name = name;
  }
}

class Cat extends Animal {
  constructor(name, breed) {
    this.breed = breed;
    super(name);
  }
}

const cat = new Cat('jane', 'black')

In the code above, we’ll get the error message ’Uncaught ReferenceError: Must call super constructor in derived class before accessing ‘this’ or returning from derived constructor’.

This is because we have to call super to make this defined. The parent constructor has to be called first to finish the configuration of this before the subclass starts the configuration of this .

Superclass doesn’t know about subclasses, so superclasses must be instantiated first.

Therefore, we need to call super before running any code that references this so that we won’t get this error.

The Cat class must be changed so that any code that references this must be moved below the super function’s call.

We should instead write:

class Animal {
  constructor(name) {
    this.name = name;
  }
}

class Cat extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
}

const cat = new Cat('jane', 'black')

In the code above, we have the super call that comes before this.breed = breed; in the constructor method.

Now we won’t get any errors when we run the code.

However, code that references this in any other method can be anywhere. For instance, if we have the following code:

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {}
}

class Cat extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  meow() {
    console.log(this.name);
    super.speak();
  }
}
const cat = new Cat('jane', 'black')
cat.meow();

In the code above, we have the speak method in the Animal class. In the Cat class, we have the meow method that references this.name before calling a method from the parent Animal class.

Conclusion

If we import multiple members from the same module, then we should put them all in one statement to save space.

The Symbol function isn’t a constructor function. To create a new symbol, we should create it by calling the Symbol function.

To make sure that our parent class instance is configured properly, then we should call super in our child class’s constructor first and then run any code that references this .

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *