ES6 Classes: OOP in Javascript
ECMAScript 2015, also known as ES6 and ES2015, introduced JavaScript Classes. Prior to ES6, JavaScript had no concept of classes and to mimic a class, constructor functions were used. JavaScript classes are syntactic sugar over the prototypal inheritance. You can think of an ES6 class as a constructor function with much prettier syntax. Using ES6 Classes, we can easily implement object oriented programming in Javascript.
Creating ES6 class
ES6 introduced a new syntax for creating classes. A class can be created either by using Class Declaration or Class Expression.
Class Declaration: The class keyword is followed by the name for the class. By convention, the first letter of the class’s name should be capital. The body of a class is the part that is in curly braces {} and this is where you define class members such as methods or constructor.
Here, we create a class called Person.
class Person {
constructor(name) {
this.name = name;
}
}Class Expression: We write the class definition and assign it to some variable.
const VariableName = class Person {
constructor(name) {
this.name = name;
}
}Creating an instance of a class
To create an instance of a class we use the new keyword. Each instance has it’s own independent copy of properties and methods of the class. Unlike function declarations, class declarations are not hoisted which means you cannot use a class before it is declared.
class Person {
constructor(name) {
this.name = name;
}
}
let person1 = new Person("John");
console.log(person1.name);Output:
JohnHere, we created an instance person1 of the class Person.
Constructor
Constructor is a function in a class which automatically runs each time an instance is created from that class. It is commonly used to set up some default data or initialize needed variables. There can be only one special method with the name constructor in a class. If we don’t specify a constructor for a class, an empty constructor is added by default and the following definition is used:
constructor() {}By convention, we should define the constructor before any method in a class but we will not get any error we don’t follow this rule.
Adding properties and methods to a class
class Person {
value = 15;
getValue() {
console.log("getValue:", this.value);
}
printMsg() {
console.log("printMsg:", this.value);
this.getValue();
}
}
let person1 = new Person();
console.log(person1.value);
person1.getValue();
person1.printMsg();Output:
15
getValue: 15
printMsg: 15
getValue: 15Here, we defined a property value and methods getValue() and printMsg() in the class Person. Properties and methods can be used in any method of the class using this keyword. For example, value and getValue() are called in printMsg() using this.value and this.getValue().
Adding a method to a class is like adding a function to the prototype object. The class keyword just makes things much easier for us. To add methods inside classes, you can add them after the constructor function. Methods can be plain functions, async functions, generator functions, or async generator functions.
this keyword
this keyword is used to refer to the instance of the class. If we define a variable in a method using this e.g. this.num, we can access it through an instance like this - person1.num.
If we want to use a variable inside multiple methods, we should define it using this.
Get Deepak Kumar Singh’s stories in your inbox
Join Medium for free to get updates from this writer.
An example:
class Person {
printMsg1() {
this.num = 10;
console.log("printMsg1: num =", this.num);
}
printMsg2() {
this.num = 20;
console.log("printMsg2: num =", this.num);
}
printMsg3() {
this.num = 30;
console.log("printMsg3: num =", this.num);
}
}
let person1 = new Person();
person1.printMsg1();
person1.printMsg2();
person1.printMsg3();
console.log("num =", person1.num);Output:
printMsg1: num = 10
printMsg2: num = 20
printMsg3: num = 30
num = 30Class Inheritance
Inheritance makes all properties and methods of the parent class available to the child class. Parent class and child class are also called superclass and subclass respectively. We use the extends keyword to create a child class.
class Person {
constructor(name) {
this.name = name;
}
getDetails() {
console.log(this.name);
}
}
class Employee extends Person {
constructor(name, company) {
super(name);
this.company = company;
}
}
const emp1 = new Employee("John", "Unilever");
emp1.getDetails();
console.log(emp1.company);Output:
John
UnileverHere, Person is parent class and Employee is child class.
extends keyword
When we want to inherit, we simply add extends keyword and the parent class name in-front of the child class similar to the syntax shown in the above code. In our example, we used extends to create the child class Employee of Person class. extends keyword adds all properties and methods (excluding the constructor) of the parent class to the child class, in addition to the properties and methods defined in the child class itself. Child class can override any method of the parent class. If constructor is not defined in the child class, a ‘hidden’ default constructor will be included automatically in the child class with the below definition:
constructor(args) {
super(args);
}Let’s see another example:
class Person {
constructor(name) {
this.name = name;
}
getDetails() {
console.log("getDetails:", this.name);
}
}
class Employee extends Person {
printMsg() {
console.log("printMsg:", this.name);
this.getDetails();
}
}
const emp1 = new Employee("John");
emp1.getDetails();
emp1.printMsg();Output:
getDetails: John
printMsg: John
getDetails: JohnMethod overriding
Overriding a method means that a child class redefines its inherited method(s) when it needs to change or extend the behavior of that method. We override a method of the parent class by defining a method with the same name (and same or different parameters) in the child class. Overriding a method replaces the code of the method in the superclass with that of the subclass. When we call the method using the instance of the subclass, the method inside the subclass is called.
JavaScript supports overriding, but not overloading. If we try to overload methods in a class, JavaScript overrides all previous definitions by the latest one. In JavaScript, all objects are instances of Object .
class Person {
getDetails() {
console.log("This is Person");
this.value = 15;
}
}
class Employee extends Person {
getDetails() {
console.log("This is Employee");
}
}
const emp1 = new Employee();
emp1.getDetails();
console.log(emp1.value);Output:
This is Employee
undefinedHere, we are overriding getdetails() method in the child class Employee.
super keyword
The super keyword is used only in a child class. The super keyword is used in two ways.
- When using in the constructor of child class, we use
super()to call the constructor of parent class. - When using in a method of child class, we use
super.methodName()to call the methodmethodNameof parent class.
If the child class has a constructor, call to super() must be the first line in the child constructor. In the child constructor, this can be used only after call to super(). You can omit super() in your subclass, if you omit the constructor altogether in your subclass.
class Person {
constructor(name) {
this.name = name;
}
getDetails() {
console.log("Person:", this.name);
}
}
class Employee extends Person {
constructor(name, company) {
super(name);
this.company = company;
}
printMsg() {
console.log("Employee:", this.name, this.company);
super.getDetails();
}
}
const emp1 = new Employee("John", "Unilever");
emp1.printMsg();Output:
Employee: John Unilever
Person: JohnPublic
This is the default nature of JavaScript. Public properties and methods are accessible outside the class also.
Private
The ECMAScript 2022 update shipped with support for private values inside JavaScript classes. Private properties and methods are accessible only inside the class. It is a syntax error to refer to private fields from outside the class. You can declare private properties inside a class by prefixing the variable with the # sign. Public and private fields do not conflict, so we can have both public and private fields with same name in a class with private field prefixed with # sign. In the below example, we can have both private #printMsg and public printMsg methods in the same class.
class Person {
#printMsg() {
console.log("A private message");
}
printMsg() {
console.log("A public message");
this.#printMsg();
}
}
let person1 = new Person();
person1.printMsg();Output:
A public message
A private messagestatic keyword
By definition, static properties and methods are bound to a class, not the instances of that class. Therefore, static methods are useful for defining helper or utility methods, such as functions to create or clone objects, whereas static properties are useful for caches, fixed-configuration, or any other data you don’t need to be replicated across instances. Static methods have no access to data stored in specific instances.
We define static properties and methods using the static keyword. Static properties and methods are called directly on the class itself. If we attempt to call a static property or method from an instance, we’ll get an error. To use a static property or method in a class method or outside the class, you use the class name followed by the . and the static method.
class Person {
static value = 15;
static greeting() {
console.log("Hello. Value is", Person.value);
}
}
console.log(Person.value);
Person.greeting();Output:
15
Hello. Value is 15





