Constructor in JS
What is Constructor in Javascript? How to use it and what is the difference between Function Constructor and Class Constructor?
What is Constructor?
A constructor is a special type of function
that is used to initialize an object when it is created. There are two types of constructors in Javascript based on syntax. The first one defined as a function
and the second one defined via a constructor method in the class
. In both cases, we use the new
keyword to create a new instance of the object.
Object Constructor Function
Default constructor in JavaScript. It existed before the introduction of the ES6 specification, i.e. before the introduction of classes
, and of course it still exists and is used.
We use the following convention when creating a constructor:
When creating the name of a constructor function, we should start with a capital first letter.
We should use the
new
operator to call the created constructor.
Example:
function Player() {
this.nickname = 'Rambo',
this.level = 1
}
We have created a constructor function called Player
, for now without any parameters inside the parentheses. Additionally, inside the constructor, we assigned the nickname
and level
properties to the word this
. And we have assigned default values for these properties (Rambo
, 1
). The this
keyword is an object that specifies a context (in this case the Player()
context), and is used to refer to that context and assign values to its properties.
Constructor usage example:
const newPlayer = new Player();
console.log(newPlayer); // Output: {nickname: 'Rambo', level: 1}
In the above example, a new instance of the Player
object was created using the new
operator, and we also assigned it to the newPlayer
constant. The value of newPlayer
is the same as Player
because we did not pass any new values to the function constructor.
Now let's try to pass the data when calling a new instance of the function constructor. For this purpose, we must specify the parameters when creating the constructor.
// Creating constructor function with two parameters
function Player(nicknameParam, levelParam) {
this.nickname = nicknameParam,
this.level = levelParam
}
const newPlayer = new Player('Terminator', 70);
console.log(newPlayer); // Output: {nickname: 'Terminator', level: 70}
In this example, we invoked a new instance of the constructor with two new arguments (Terminator
, 70
) that were assigned to the nickname
and level
properties from the context of the Player
object. These values were returned when newPlayer
was called.
Why are these values returned even though we don't see the return
declaration there? Because the return
declaration is added at the end by JavaScript, when the new
operator is used and a new instance of the object is invoked.
function Player(nicknameParam, levelParam) {
// this = {}; <- creating empty object for context
this.nickname = nicknameParam,
this.level = levelParam
// return this;
}
Therefore, it is important to use the new
operator when creating a new object. Without it, JS will read the call as a function
without a return
declaration and return undefined
.
function Player(nicknameParam, levelParam) {
this.nickname = nicknameParam,
this.level = levelParam
// no return statement
}
const newPlayer = Player('Terminator', 70);
console.log(newPlayer); // Output: undefined
Class constructor
In the ES6 specification (ECMAScript 2015), classes
were introduced into the JacaScript syntax, and it is possible now to use a constructor within them.
Like function constructor
, class constructor
is a special method for configuring new objects, but now integrated into the class structure. This makes the syntax clearer and the constructor can e.g. access and use class features such as inheritance using the super
keyword.
Below is the same example we already know, but using class
:
class Player {
constructor(nicknameParam, levelParam) {
this.nickname = nicknameParam;
this.level = levelParam;
}
}
const newPlayer = new Player('Terminator', 70);
console.log(newPlayer); // Output: {nickname: 'Terminator', level: 70}
Above we used the classPlayer
and in it we defined a constructor
with parameters and properties. Notice that now the constructor is created using the constructor
keyword. To create a new instance of class, or more specifically the constructor of the Player
class, we still use the new
operator, and in this case we even have to, because JS requires it. If we do not do this, we will receive an error.
It is possible to omit the constructor when creating a class if we do not use any additional object initialization.
class Player {
nickname = 'Rambo';
level = 1;
}
const newPlayer = new Player();
console.log(newPlayer); // Output: {nickname: 'Rambo', level: 1}
Inheritance
As mentioned earlier, in ES6 classes introduce the possibility of inheritance, i.e. the ability to take over the entire functionality of the parent class
and the possibility of adding additional classes.
For better understanding, I will explain it with an example:
class PlayerInfo {
constructor(nicknameParam, levelParam) {
this.nickname = nicknameParam;
this.level = levelParam;
}
getPlayerInfo() {
return `Your character ${this.nickname} has level ${this.level}.`
}
}
const newPlayerInfo = new PlayerInfo('Terminator', 70);
console.log(newPlayerInfo.getPlayerInfo());
// Output: Your character Terminator has level 70.
We have created a base class
that takes two parameters nicknameParam
, levelParam
and has a getPlayerInfo
function that returns text.
Now let's try to create another one that will inherit from the PlayerInfo
class:
class PlayerFullInfo extends PlayerInfo {
constructor(nicknameParam, levelParam, activeSubscribtionParam) {
super(nicknameParam, levelParam);
this.activeSubscribtion = activeSubscribtionParam;
}
getPlayerInfo() {
const subsctibtion = this.activeSubscribtion ? 'active' : 'inactive';
return `Your character ${this.nickname} has level ${this.level}
and your subscribtion is ${subsctibtion}.`;
}
}
const newPlayerFullInfo = new PlayerFullInfo('Rambo', 20, true);
console.log(newPlayerFullInfo);
// Output: {nickname: 'Rambo', level: 20, activeSubscribtion: true}
console.log(newPlayerFullInfo.getPlayerInfo());
// Output: Your character Rambo has level 20 and your subscribtion is
// active.
When creating a new PlayerFullInfo
class, we used the extends
keyword to indicate which class we will inherit from.
Then we used the super
keyword in the constructor properties to call the code from the constructor of the class we are extending. Additionally, we created the getPlayerInfo()
method which, although it has the same name as in the PlayerInfo
class, is overwritten and returned when newPlayerFullInfo.getPlayerInfo()
is called.
Why do we need a constructor?
By using a constructor function, you can easily create multiple objects with the same properties and behavior without having to manually set them for each object. We also gain benefits such as: encapsulation, inheritance, so our code becomes more reusable, consistent and easier to maintain.