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
.