Classes in JavaScript

Classes in JavaScript

Introduction

Classes in javascript

Classes in JavaScript are just a different way of representing constructor functions and methods from “prototype objects”, but without fundamentally changing the inheritance mechanism itself. Background class inheritance is the well-known mechanism of “method delegation” through the “prototype chain of inheritance”.
In JavaScript, the reserved word “class” only indicates that the query is a special type of function, which, unlike a regular function, cannot be called (invoke), but can only be used with the reserved word “new”.
This functionality was introduced into the language with the ES2015 standard, with the intention of improving readability and facilitating the writing of object-oriented programs. When defining the appearance of the syntax, the designers of the standard were guided by the idea of ​​creating such a syntax that will resemble the syntax of most “class” languages”, and thus help programmers who already program in a “class” language” to more easily adopt the JavaScript syntax.
If in the following examples we compare parts of the code written with different syntaxes, we can see that the class syntax is better readable compared to the ES5 syntax:

Example: ES5 syntax

Example: Class Syntax

The layout of the class is very similar to the object creation syntax according to the ES5 standard, although it is more readable due to fewer lines and unnecessary parts removed:

NOTE:
Unlike other “class languages”, creating objects in Javascript (even when using classes) is not static ie. is not immutable after the object‘s declaration. In JavaScript, an object after instantiation remains “bound” to the class, with its “prototype object” through the chain of inheritance. Therefore, if we subsequently add or change a method in the class itself, that change will be felt by every object instantiated on the basis of that class.

Basic features

Creating classes

Since classes are still just functions, as with all functions there are two ways to create them:

  1. Function declarations

    This is the most common way to write classes:

    The main difference between a function declaration and a class declaration is that classes are not “hoisted” when compiled to the beginning of the program code as a function. So care should be taken to define the class before using “new” to create a new object.

  2. Function expressions

    This approach is less commonly used, but a completely legal way to create classes:

    As with ordinary “function expressions“, there is no hoisting here either.

NOTE:
The body of the class is executed in “strict mode”.

Methods

Ordinary methods

We define methods as functions, but without the function keyword. Although it should be noted that the methods inside the class have the “enumerable” property set to false, which means that no “for..in” loops are available at the start.

Constructor method

A constructor is a special method that creates and initializes an object. This method is the counterpart to the constructor function from ES5, it defines everything needed to initialize a new object, with the note that there can only be one constructor method within a class.

Static methods

Static methods are methods that do not belong to the instantiated object, but to the class itself, therefore they cannot be accessed from the instantiated object. The only access to these methods is through the class itself. Such methods are defined by using the reserved word “static” in front of the method name.

Get and Set methods

In many programming languages, access to private properties is achieved using special methods called “get-era” and “set-era”. This is also the case with JavaScript, where such methods within a class are indicated by adding the reserved word “get/set” before the method name itself.

Example

NOTE:
Get/Set methods are defined within the class as methods, but they are accessed in the same way as if they were properties of the object.
a) This method is accessed inside some other method as if it were an ordinary object property:

b) The “Get” method is also called in the newly generated object as a property of the object:

c) Even the “set” method is approached as assigning a value to an ordinary object property:

Class inheritance

Syntax

Inheriting classes requires the extends keyword and the name of the inherited object to be used in the class declaration itself. The declaration in the following example Successor extends Parent “tells” us that the Successor.prototype object is connected to the Parent.prototype object.

When creating a new class that inherits another class, we have the obligation that when defining the constructor function, we must call the constructor function of the parent class inside it. Reservations The word super indicates the parent constructor function, and the “super()” method is used to call the constructor of the base class. This base class constructor call must be made at the very beginning of the constructor function! (because it defines the keyword “this”. )
If we do not call the “super()” method within our constructor function, the JavaScript engine will throw an error: “Must call super constructor in derived class before accessing ‘this’ or returning from derived constructor”. The error will occur even if we don’t use “this” in our constructor, as in the following example:

So, if we have a constructor method in the new class (even if it is empty) “we have to call the super() method”!

EXPLANATION:
By calling the super() method, we execute the entire code from the basic constructor function and define that this points to the newly generated objects.

What happens if the new class does not have a constructor() method defined?

In this case, JavaScript creates its own internal (hidden) constructor function for us, which looks like this:

Base class property access

Property frombase classes are accessed by default with “this.property”:

Base class method access

The reserved word super represents the “parent” constructor, so when we need access to a method from the base class, we access it with “super.methodname”: