Lead Developer @Thoughtworks.
JavaScript and OpenSource enthusiast.

Pseudoclasses and prototypal inheritance in JS

This is my third post in the series of “JS: Leave the classes to those other languages”. If you haven’t checked out the first two posts, you can read them on JS: Leave the classes to those other languages and JS Prototype chain mechanism.

Real classes (classical inheritance)

Before diving into pseudoclasses it is important to point out some characteristics of real classes (classes in Java, Ruby, etc).

class Person
  attr_reader :name

  def initialize(name)
    @name = name

class Student < Person
  attr_reader :school

  def initialize(name, school)
    @school = school

giamir = Student.new('Giamir', 'TW University')

puts giamir.name # "Giamir"
puts giamir.school # "TW University"

In traditional languages:

  • Classes are blueprints
  • Objects (instances) are copies of all the characteristics described by classes

Here giamir is an instance of Student and when we send to it the message name or school, giamir knows how to handle the message without asking or delegate to some other objects.

In JS this is not possible because JS doesn’t copy object properties (natively, by default).

Pseudoclasses (prototypal inheritance)

Prototypal inheritance is the most popular way to fake classes (work with pseudoclasses) in JS. The following code implement a pseudoclass Person and a pseudoclass Student that “inherits” from Person. It’s also creating an “instance” of the pseudoclass Student and assigned it to a variable giamir.

function Person(name) {
  this.name = name;

Person.prototype.getName = function() {
  return this.name;

function Student(name,school) {
  Person.call( this, name ); // pseudo-polymorphism
  this.school = school;

Student.prototype = Object.create(Person.prototype);

Student.prototype.getSchool = function() {
  return this.school;

var giamir = new Student('Giamir','TW University');

giamir.getName(); // "Giamir"
giamir.getSchool(); // "TW University"

Here is a mental map of the prototype chain generated by the code above.


We create a function Person and a function Student and we want to use them as constructors. Functions in JS automatically get a property called prototype, which is just an empty object internally linked to Object.prototype.

We use explicit pseudo-polymorphism to delegate between Student and Person constructors. We call the Person constructor in the context of the new object we are creating using the Student constructor.

Person.call( this, name ); // pseudo-polymorphism

Obviously we want the Student.prototype object be able to use all the Person.prototype methods. To do so we need to replace Student.prototype with a new object that delegates to Person.prototype instead of Object.prototype. The easiest way to do that is using the ES5 Object.create() method:

Student.prototype = Object.create(Person.prototype);

Once that the prototype chain is in place we can create a new object giamir using the Student function as a constructor:

var giamir = new Student('Giamir','TW University');

Here giamir is an object that delegates to Student.prototype and when we send to it the message getSchool for example, giamir has to delegate the message to the object above it in the prototype chain and so on.

Inheritance or delegation?

The word “inheritance” has a very strong meaning with plenty of mental precedent. Merely adding “prototypal” in front to distinguish the actually nearly opposite behaviour in JS is inappropriate.

JS creates a link between two objects, where one object can essentially delegate property/function access to another object.
Delegation is a much more accurate term for JavaScript’s object-linking mechanism.

If you’re creating constructor functions and inheriting from them, you haven’t learned JavaScript. It doesn’t matter if you’ve been doing it since 1995. You’re failing to take advantage of JavaScript’s most powerful capabilities.
You’re working in the phony version of JavaScript that only exists to dress the language up like Java.

– Eric Elliott

We are ready to explore alternative patterns in JS to get rid of pseudoclasses and finally embrace the nature of the language.

Giamir Buoncristiani

Giamir Buoncristiani

Lead Developer @Thoughtworks.
JavaScript and OpenSource enthusiast.