Object-Oriented Javascript Methods: Comparing Pseudo-Classical, OLOO, and the 2015 Class Syntax

Javascript’s prototypal inheritance is simple; so simple, in fact, that it can seem at times overly-complicated. There’s just so many ways to do inheritance! But at it’s heart, JS has only one construct: objects. And objects can be linked with other objects in a prototype chain.

The focus of this article is not to go into detail about the exact implementation of JS’s OOP. MDN’s stellar documentation, as always, provides in-depth and easily parsed documentation. If you’re trying to wrap your head around JS’s OOP implementation, start with MDN’s Object-oriented JavaScript for beginners and when you’re ready, make sure to read Inheritance and the prototype chain.

I also won’t go into depth about all the ways in which JS OOP might be implemented in the wild. John Dugan does a stellar job of taking us through a myriad of approaches.

Instead, I’m comparing two approaches that many agree are best-practice: the pseudo-classical model, and Kyle Simpson’s OLOO model. I’ll show examples of the classical model using more conventional code, and the updated 2015 syntax using the class keyword.

First up, let’s look at the most common implementation of JS’s OOP, the so-called pseudo-classical model, which looks similar in syntax to many classical approaches to OOP, such as those found in Ruby, Python, and Java.

Pseudo-Classical Example:

function Animal(name) {
  this.name = name;
}
// constructor function is defined

function Dog(name) {
  Animal.call(this, name);
}
// a second constructor function is defined, utilizing `call` to call the
// `Animal` function with `this` and `name` argument

Dog.prototype = Object.create(Animal.prototype);
// `Dog` prototype is set to be a copy of `Animal` prototype

Dog.prototype.constructor = Dog;
// fix the constructor, so that objects created from `Dog` will correctly show
// `Dog` as the constructor

Dog.prototype.barks = function() {
  console.log(`${this.name} barks!`);
}
// Add a `bark` method to the `Dog` prototype

const sparky = new Dog('Sparky');
sparky.bark();

Advantages:

Disadvantages:

Example Using 2015’s Class Syntax:

class Animal {
  constructor(name) {
    this.name = name;
  }
}
// constructor function defined

class Dog extends Animal {
  constructor(name) {
    super(name);
  }

  barks() {
    console.log(`${this.name} barks!`);
  }
}
// a second constructor function defined, using `super` to pass arguments to the
// first constructor function, and implementing the `bark` method

const sparky = new Dog('Sparky');
sparky.barks();

Advantages:

Disadvantages:

OLOO (Objects Linked to Other Objects) Example:

const Animal = {
  init(name) {
    this.name = name;
    return this;
  },
};
// notice this is an object, and not a function
// also notice the `init` method, which sets initial values

const Dog = Object.create(Animal);
// creating an object from the first object, which establishes a link in the
// prototype chain

Dog.bark = function() {
  console.log(`${this.name} barks!`);
};
// add a method to the `Dog` object

const sparky = Object.create(Dog).init('Sparky');
// creates a new object from `Dog` and passes in the name `Sparky`

sparky.bark();

Advantages:

Disadvantages:

Summary

Recommendations