Javascript – Classes

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
JavaScript

Before 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.
JavaScript

With ES6

There are two ways of declaring a class.

  1. Class declaration
  2. 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.
JavaScript

Class Expression

We can assign the class expression to the variables.

  1. Unnamed class expression
  2. 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.
JavaScript

constructor() 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
JavaScript

Accessor Properties

There are two accessor properties, which we can use with class.

  1. Set – To set the value of any property
  2. 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
JavaScript

Computed 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
JavaScript

Accessor 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
JavaScript

Advantages 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 throw error. Also all the methods declared inside class lack construct method and calling them with new keyword will result in error.
  • Declaring the method name same as class name inside class will result in error

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *