The full video and many others like it are all available as part of our Frontend Masters subscription.

Kyle Simpson

Kyle Simpson is an Open Web Evangelist from Austin, TX, who's passionate about all things JavaScript. He's an author, workshop trainer, tech speaker, and OSS contributor/leader.

Kyle Simpson

You Don't Know JS

In classical inheritance, properties and methods of a class are copied to object instantiated of that class. Subclasses inherit the properties and methods of a parent class and copy them to their instantiated objects. Kyle contrasts that with JavaScript's "prototypal inheritance" or "behavior delegation"

Get Unlimited Access Now

Kyle Simpson: So let's talk a little bit about the formalities of what classes imply for us. And let's kind of give some specificity to why JavaScript isn't working the way that we thought it should work. In classical inheritance, we have a parent class that we call foo. And when we instantiate foo and we create an a1 instance of foo, there is a copy of behavior from the parent class into the child.

And there's another copy that happens when foo gets copied into a2. And when we create a child class called bar we're copying the behavior from foo down to bar and then another copy into bar's instances. This is not only a physical thing in terms of what the compiler is doing, but this is the most common way that metaphorically we explain how classes work, if any of you ever took computer science classes or whatever.

If you were ever taught, you were probably given the metaphor of the blueprints. The class represents the blueprints for some building, and then, so you have an architect that lays out the blueprints, but you have a builder than comes along and builds your building. Well, the builder is copying the characteristics from the plans into the physical building.

Once the physical building is built, there's no more relationship to the original plans. It's not like they're linked or tied in some way. It was a copy. So we can go back to biology and we can talk about parents and children. And when my child inherits my DNA, they get a copy of my DNA.

There's no linkage. When my son breaks his leg, I don't break my leg. There's no linkage between the two because everything about inheritance, the word inheritance means copy. Okay? So, if the mechanism in JavaScript doesn't do copying, that's why I think it's wrong to call it inheritance. because we're using a word in the wrong way.

Now, there are some people that call this prototypal inheritance. There are some people that say JavaScript doesn't have inheritance, what it has is prototypal inheritance. In other words, we stick the word prototypal in front of the word inheritance, and somehow magically, we've divorced ourself from the fact that inheritance means something very different.

To me, that's like me holding up an apple in one hand and an orange in the other hand and saying, no, no, no, that's not an apple, it's just a red orange. You would look at me and say, that's ludicrous. Just because you put the word red in front of it doesn't make it an orange.

Or doesn't make it not an apple. It intrinsically is something based upon its characteristics, and what you call it, you can call it what it is or you can call it something else and confuse me. But what you call it doesn't change what it is. So in my opinion, inheritance means something.

And we can't just put the word prototypal in front of it and make it mean something else. And not just something else, something completely opposite, is what I'm about to illustrate. Okay? So in JavaScript, the way things work, this is called prototypal inheritance. In JavaScript we have an object, it's arbitrarily labeled Foo.prototype and when we create the a1 object, you notice that the arrow now goes in the opposite direction, because it wasn't a copy at all.

It was a behavior link. It was a delegation link. So a1 is linked to foo.prototype, and a2 is linked to foo.prototype, and Bar.prototype is linked, and b1 and b2. The arrows go from right to left, and bottom to top, which is the complete opposite of the previous slide.

These mechanisms are fundamentally, in their very intrinsic DNA, they are opposite of each other. One of them is a copy down, one of them is a delegation up the chain. And what we've been trying to do for 20 years is make a mechanism that works like this pretend like it's a mechanism from the previous slide.

And we've been doing all kinds of things. You've heard of the mix in pattern, which manually copies things from one prototype to another and all manner of different variations on it. I could spend hours and hours talking about all the different variations. 100% of that is an attempt to make something that works like this look like it works like the previous slide.

So we're doing all of this work, and I think it's just hiding the fact that we could look at a mechanism that works like that and see how we could take advantage of that mechanism itself. Because that mechanism has a lot of power to it. This is another design pattern by the way.

And that design pattern is called behavior delegation. So rather than saying that JavaScript has inheritance or prototypal inheritance or whatever other type of silly label you want to put on it, I think it's more important to say that JavaScript has behavior delegation, and that's a design pattern we can adopt in our code.

Remember this code before when we say a1.speak? I've already used this word before but when a1 is able to call speak, you notice the way that the mechanism works. It wasn't because a1 got a copy of speak. The reason a1 was able to call speak is because he was able to delegate up to a different object that had a speak method on it.

It's a completely different mechanism than what happens with classes.

Ready to take your code to the next level?

Intense courses with world-class teachers and unlimited access to our growing library of videos for the great price of $39 per month.

Get Unlimited Access Now