As you might already know javascript is a prototype-based language. It was not designed to object-oriented but as the javascript was getting popular there were different libraries which were trying to extend javascript to be class based. So ES6 introduced class in javascript.
Classes are primarily syntactical sugar over js’s existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to Javascript.
Classes are blueprint for creating objects, providing a more structured way of defining constructor functions.
MDN
class Rectangle {
constructor (width, height) {
this.width = width;
this.height = height;
}
getArea () {
return this.width * this.height;
}
}
const rect = new Rectangle(5,10);
console.log(rect.getArea()); // 50
JavaScriptBefore diving deep in to the javascript class, let us first understand how different object-oriented concepts were handled through the prototype.
Before ES6
Functions were used to replicate class.
// creating new function
function individual(name, age) {
this.name = name; // declaring properties
this.age = age;
this.details = function() { // one way to declare the method
return this.name + ' is ' + this.age + ' years old.';
}
}
// second way, By declaring the method through prototype
individual.prototype.details = function () {
return this.name + ' is ' + this.age + ' years old. ';
}
// calling the function as class
let person1 = new individual('sujay', 23);
let person2 = new individual('sanket', 18);
console.log(person1.details());
// sujay is 23 years old.
JavaScriptWith ES6
There are two ways of declaring a class.
- Class declaration
- Class expression
Class declaration
class Individual {
// declaring properties inside constructor
constructor(name, age) {
this.name = name;
this.age = age;
}
// declaring display method
details() {
return `${this.name} is ${this.age} years old.`;
}
}
// creating a person object from individual class
let person = new Individual('sujay', 23);
// calling the display method
console.log(person.details());
// sujay is 23 years old.
JavaScriptClass Expression
We can assign the class expression to the variables.
- Unnamed class expression
- Named class expression
// unnamed class expression
class Person = class {
// declaring properties inside constructor
constructor(name, age) {
this.name = name;
this.age = age;
}
// declaring display method
details() {
return `${this.name} is ${this.age} years old.`;
}
}
// named class expression
const Person = class Individual {
// declaring properties inside constructor
constructor(name, age) {
this.name = name;
this.age = age;
}
// declaring display method
details() {
return `${this.name} is ${this.age} years old.`;
}
}
// creating a person object from individual class
let person = new Individual('sujay', 23);
// calling the display method
console.log(person.details());
// sujay is 23 years old.
JavaScriptconstructor() should be declared only once.
As you can see class works similar to the prototype based approach. But there are many advantages of using classes.
Static Methods
Static methods are only accessible by parents(class), derived child or instance of the class
cannot access them.
class Person {
// declaring properties
constructor (name, age) {
this.name = name;
this.age = age;
}
// declaring method
// accessible by all
details() {
return `${this.name} is ${this.age} years old.`;
}
// static method
// accessible only by parent (Person)
// can not accessed by derived child or instance of the class
static display() {
console.log(`I am only accessible by parent.`);
}
}
// Input
let person1 = new Person('sujay', 23);
person1.details(); // sujay is 23 years old
Person.display(); // I am only accessible by parent
person1.display(); // Uncaught: TypeError: person1.display is not a function
JavaScriptAccessor Properties
There are two accessor properties, which we can use with class.
- Set – To set the value of any property
- Get – To get the value of any property
class Person {
// declaring properties
constructor(name, age) {
this.name = name;
this.age = age;
}
// set name
set nickName (name) {
this.name = name;
}
// get name
get nickName () {
return `your name is ${this.name}`
}
}
let person1 = new Person('Sujay Kundu', 23);
console.log(person1.nickName); // your name is Sujay Kundu
// set the new nickname
person1.nickName = 'Babu';
console.log(person1.nickname); // your name is Golu
JavaScriptComputed Method Names
Class methods and accessor properties can be computed names, that means their names can be provided at runtime.
// declaring the method name
let myMethod = 'displayDetail';
class Person {
// declaring properties
constructor(name, age) {
this.name = name;
this.age = age;
}
// declaring a method with the computed name
[myMethod](){
return `${this.name} is ${this.age} years old`;
}
}
let person = new Person('Sujay Kundu', 23);
console.log(person.displayDetail()); // computed
// Sujay Kundu is 23 years old
JavaScriptAccessor properties can also use computed methods.
let myMethod = 'differentName';
class Person {
// declaring properties
constructor(name, age) {
this.name = name;
this.age = age;
}
// Set name
set [myMethod](name) {
this.name = name;
}
// Get name
get [myMethod](name) {
return `your name is ${this.name}`
}
}
let person1 = new Person('Sujay Kundu', 23);
console.log(person1.differentName); // your name is Sujay Kundu
// set the new differentName
person1.differentName = 'Golu';
console.log(person1.differentName); // your name is Golu
JavaScriptAdvantages of using classes:
- Unlike functions, class declarations are not hoisted. which means variables declared inside are not accessible outside. They remain in temporal dead zone just like
let
until execution reaches the declaration. - Code inside
class
runs in strict mode. - Methods declared inside class are non-enumerable. Unlike prototype based where we had to use
Object.defineProperty()
to make method non-enumerable. - Calling the class constructor without
new
keyword will throwerror
. Also all the methods declared inside class lackconstruct
method and calling them with new keyword will result in error. - Declaring the method
name
same asclass name
insideclass
will result inerror