Published on

JavaScript Class Instantiation Patterns

Authors

Like in pretty much all things in life, there are several ways you do things. Over the past few months as I've been deep diving into javascript. I've come across several ways you can create "classes" in the language. I recall the frustration I had when I first started learning about this topic, so today I'd like to briefly share with you the different class instantiation I've learned.

Functional Pattern

const Car = function (color) {
const obj = {}
obj.color = color
obj.door = 'closed'
obj.doorOpen = function () {
obj.door = 'open'
}
obj.closeDoor = function () {
obj.door = 'closed'
}
return obj
}
const car = Car('red')

Pros:

  • clear object construction
  • everything that is being done is contained inside the function

Cons:

  • Methods duplicated for every object we create, so new spot in memory created.
  • Not ideal if your creating multiple instance of objects.

Functional shared pattern

//Functional-shared pattern
const Car = function (color) {
const obj = {}
obj.color = color
obj.door = 'closed'
obj.openDoor = carMethods.openDoor
obj.closeDoor = carMethods.closeDoor
return obj
}
const carMethods = {}
carMethods.openDoor = function () {
this.door = 'open'
}
carMethods.closeDoor = function () {
this.door = 'closed'
}
const car = Car('red')

Pros:

  • clear object construction
  • no duplication of methods each time we create an instance

Cons:

  • Setting method pointer is less efficient than delegating a fallback
  • Not ideal, if your creating multiple instances of objects.

Prototypal Pattern

const Car = function (color) {
const obj = Object.create(Car.prototype)
obj.color = 'color'
obj.door = 'open'
return obj
}
//Automatically created by interpreter
//Car.prototype = {};
Car.prototype.openDoor = function () {
this.door = 'open'
}
Car.prototype.closeDoor = function () {
this.door = 'closed'
}
const car = Car('red')

Pros:

  • clear object construction
  • no duplication of methods each time we create an instance

Cons:

  • Setting method pointer is less efficient than delegating a fallback
  • Not ideal, if your creating multiple instances of objects.

Pseudoclassical Pattern

const Car = function (color) {
//Automatically created by interpreter
//const this = Object.create(Car.prototype);
this.color = color
this.door = 'open'
//return this;
}
const car = new Car('red')

Pros:

  • Most memory efficient and standard method of creating classes in javascript (prior to ES6 classes)

Cons:

  • more magic involved than the prototypal pattern (see above)

ES6 Class Pattern

class Car {
constructor(color) {
this.color = color
}
openDoor() {
this.door = 'open'
}
closeDoor() {
this.door = 'closed'
}
}
const car = new Car('red')

Pros

  • Syntax is the most clear among the others as it matches class syntax of other popular programming languages

Cons

  • For those coming from other common different programming languages (Ex: Java, Python, C# etc), the syntax for creating classes in Javascript can be decieving at a first glance and it doesn't reflect how classes work in other languages. To implement inheritance, Javascript uses prototypal inheritance under the hood. In fact, the class keyword syntax gets translated to Pseudoclassical pattern

Which One Should I Use?

The majority of code bases use the class syntax and I believe you should too. You'll often see older code bases still use the Pseudoclassical pattern.

References and Resources