Prototypal Inheritance in JavaScript

Last year I wrote a post called “How to impress me in an interview”, and in it, I mentioned that I run across a lot of candidates (the vast majority, actually) who don’t really understand how prototypes work.

In a way, that’s kind of an amazing testament to how flexible JavaScript is, and how user-friendly many of today’s popular libraries are. I can’t think of many other object-oriented languages where an engineer can be reasonably productive without being at least vaguely aware of classes.

But here’s the thing: if you write JavaScript even semi-regularly, you really should understand how prototypal inheritance works. And that’s why I’m writing this post.


My goal here is to help someone who’s never used prototypal inheritance to become comfortable with it. In order to do that, I’ll cut a few small corners here and there if I think it helps eliminate a bit of confusion.

Objects Inherit from Objects

This is true, and once you already understand it, it’s a good way to think about things. But my experience has been that this explanation alone isn’t really sufficient.

So I’m going to break from tradition here and not actually try to explain how inheritance works right up front. Instead, we’ll start with some simpler stuff that will hopefully provide a bit of context later on.

Function prototypes

function foo() {}typeof foo.prototype // ‘object’

That’s pretty simple, right? Any time you create a function, it will automatically have a property called prototype, which will be initialized to an empty object.


By the way, if you don’t know what I mean when I say “constructor”, that’s totally okay. We’ll get there.

So let’s say that we want to make a constructor function called Dog, because explaining inheritance using animals is a time-honored tradition and I’m kind of a nostalgic dude.

function Dog() {}

If I want to make an instance of Dog, I use the new keyword. That’s really what I mean when I talk about constructors — I’m using the function to construct a new object. Any time you see the new keyword, it means that the following function is being used as a constructor.

var fido = new Dog();

So now we have fido, who’s a Dog. But he doesn’t really do anything.

He’s kind of like my dog, actually.


function Dog() {}Dog.prototype.bark = function() {

You should remember from earlier that all functions automatically get initialized with a prototype object. In the example above, we tacked a function onto it called bark.

Now let’s make ourselves a new fido.

function Dog() {}Dog.prototype.bark = function() {
var fido = new Dog();fido.bark(); // ‘woof!’

I’m going to explain this in more detail a little later on. But the important thing to take away right now is that by placing bark on Dog.prototype, we made it available to all instances of Dog.

Don’t worry yet about how this works. Just keep in mind that it works.

Differential Inheritance

For example, fido doesn’t actually have its own method called bark() (in other words, fido.hasOwnProperty(‘bark’) === false).

What actually happens when I write fido.bark() is this:

1. The JS engine looks for a property called bark on our fido object.
2. It doesn’t find one, so it looks “up the prototype chain” to fido’s parent, which is Dog.prototype.
3. It finds Dog.prototype.bark, and calls it with this bound to fido.

That part is really important, so I’m going to repeat it:

There’s really no such property as fido.bark. It doesn’t exist. Instead, fido has access to the bark() method on Dog.prototype because it’s an instance of Dog. This is the “invisible link” I mentioned. More commonly, it’s referred to as the “prototype chain”.


Since ES5, JavaScript has had a cool little function called Object.create().

Here’s how it works.

var parent = {
foo: function() {
var child = Object.create( parent );child.hasOwnProperty(‘foo’); // false; // ‘bar’

So what is it doing?

Essentially, it creates a new, empty object that has parent in its prototype chain. That means that even though child doesn’t have its own foo() method, it has access to the foo() method from parent.

Try It

Create a constructor function called Car. Add a drive() method to its prototype that just logs to the console. Now create an instance of Car and call drive().

I really mean it. You should take 30 seconds and go do it. I’ll wait here. And no cheating…

Good, you’re back. Hopefully you wrote something that looks like this.

function Car() {} = function() {
var benz = new Car();; // vroom

If not, consider re-reading some of the earlier sections. It’s important that you’re somewhat comfortable with that stuff before you move on.

Putting It All Together

Let’s start by creating a Rectangle constructor.

function Rectangle( width, height ) {
this.width = width;
this.height = height;

At this point, we’ll take a tiny detour to talk about this.

When a function is used as a constructor, this refers to the new object that you’re creating. So in our Rectangle constructor, we’re taking width and height as arguments, and assigning those values to the width and height properties of our new Rectangle instance.

var rect = new Rectangle( 3, 4 );rect.width; // 3
rect.height; // 4

Now it’s time to give our Rectangle a method. Let’s call it area.

Rectangle.prototype.area = function() {
return this.width * this.height;

There’s that this keyword again. Just like in the constructor, this inside of a method refers to the instance.

var rect = new Rectangle( 3, 4 );rect.area(); // 12


Let’s say we need a class called Square. Hopefully you remember from elementary school that a square is just a specific type of rectangle.

We’ll start by creating its constructor.

function Square( length ) {
this.width = this.height = length;

So, that’s all well and good, but how do we make Square inherit from Rectangle? It’s all about setting up the prototype chain.

If you remember from earlier, we can use Object.create() to create an empty object that inherits from another object. In the case of Square, that means all we need to do is this:

Square.prototype = Object.create( Rectangle.prototype );

All instances of Square will automatically have Square.prototype in their prototype chain, and because Square.prototype has Rectangle.prototype in its prototype chain, every Square will have access to the methods of Rectangle.

In other words, we can do this:

var square = new Square( 4 );square.area(); // 16

We can also add new methods that are specific to Square. Remember, Square.prototype is just an empty object right now (albeit with a link back to Rectangle.prototype).

Square.prototype.diagonal = function() {
return Math.sqrt( this.area() * 2 );

Time travel

Because JavaScript will look up the prototype when trying to access properties on an object, you can alter your classes at runtime.

Here’s an example (for illustrative purposes only. Don’t ever do this):

var arr = [ 1, 2, 3, 4, 5 ];Array.prototype.shuffle = function() {
return this.sort(function() {
return Math.round( Math.random() * 2 ) — 1;
arr.shuffle(); // [ 3, 1, 4, 5, 2 ]

The important thing to notice in this example is that arr was created before Array.prototype.shuffle existed. But because property lookups go up the prototype chain, our array got access to the new method anyway — because it existed on Array.prototype by the time we tried to actually use it. It’s like we went back in time and gave Array a (stupid) new method.

To get a sense of how powerful (and potentially dangerous) this is, go open the JS console on a page like Facebook, paste in the following code, and watch the log as you click around:

Array.prototype.push = function() {
throw new Error(‘lolnope’);


Just wanted to leave one final note on constructors, which I realized may have been a little unclear…

function Rectangle( width, height ) {
this.width = width;
this.height = height;
Rectangle.prototype.area = function() {
return this.width * this.height;
var shape = new Rectangle( 3, 4 );

What the new keyword actually does here is, essentially:

  1. Create an empty object that has Rectangle.prototype in its prototype chain.
  2. Call Rectangle with the this bound to the new object.

So there’s really no magic there at all.

It’s kind of the same as saying:

function Rectangle( width, height ) {
this.width = width;
this.height = height;
Rectangle.prototype.area = function() {
return this.width * this.height;
var shape = Object.create( Rectangle.prototype ); shape, 3, 4 );

— -

If you live in the Boston area, love JavaScript, and want to work on some really exciting problems at Starry, shoot me an email. I’m hiring.

Director of Engineer and founding team member @StarryInternet. Formerly @Aereo. @kevincennis on Twitter and Github.

Director of Engineer and founding team member @StarryInternet. Formerly @Aereo. @kevincennis on Twitter and Github.