Check out a free preview of the full The Good Parts of JavaScript and the Web course:
The "Pseudoclassical Inheritance" Lesson is part of the full, The Good Parts of JavaScript and the Web course featured in this preview video. Here's what you'd learn in this lesson:

JavaScript was designed with a prototype object. Inheritance easy to implement through this prototype object, however, it has a lot of shortcomings. Doug spends some time looking at how prototypical inheritance works in JavaScript and identifies the areas where problems arise.

Get Unlimited Access Now

Transcript from the "Pseudoclassical Inheritance" Lesson

>> [MUSIC]

>> Douglas Crockford: Let's get into an object oriented programming, what do you say? So when Brendan Eich designed JavaScript, he was very strongly influenced by a paper that he read about the self project. And the self project was into prototypes not into classes. And he thought, wow that's pretty neat.

[00:00:24] So he decided to put that in his language but he didn't fully understand it or have confidence in it. So he came up with something kind of intended to be more classical thinking that the classical guys would like it better. So this is the original intended model for how you were supposed to use JavaScript.

[00:00:43] So we're gonna make a Gizmo. That's our Gizmo constructor function. We'll pass in an ID and we'll create a property of the object with an, that is named ID, which will get that value. And we want our gizmos to inherit a t0String method. So the way you do that is use a gizmo.prototype.toString = function.

[00:01:07] In that function implements the toString method. And the Java programmers looked at this and said, what the hell is that, I mean this is awful looking that what's this .prototype crap? Why you leaking your stuff and nothing's contained in anything, right? You want to have your class have some integrity, like it's wrapped in something.

[00:01:31] And this has its guts spilled all over the place. This is just really awful. But this is how Brendan thought the language was going to work. So let me diagram this for you, so you can see what's actually going on. So this is that code, put up on the screen, new gizmo is how we make the instance.

[00:01:50] So this is the instance of the gizmo, we see the ID property that the constructor put in it. This is the gizmo function because in this language functions are objects, so they can also have properties. Every function is born with a prototype property, just in case it's going to be used as a method or as a constructor.

[00:02:13] And the gizmo.prototype is this object. This is gizmo.prototype and it contains these fields. This is the toString method that we assign there. And the system also has the object function that's the constructor of all objects. And we've already talked about object.prototype, that's the thing that all object literals inherit from.

[00:02:37] So we can add a constructor link here. The constructor property contains a reference to the constructor, so gizmo.prototype.constructor is gizmo. And similarly object.prototype.constructor is object. You can even go around that loop as many times as you want,
>> Douglas Crockford: But the important thing is the delegation link, the inheritance link.

[00:03:05] So our instance inherits from gizmo.prototype and gizmo.prototype inherts from object.prototype. So if I ask my instance for an ID, ID we find it here, we return the string. If I ask my instance for it's tooS method, it goes I don't have one, he's got one so we return this function as though It were part of this object.

[00:03:32] And if we ask for its foo property, he doesn't have one, he doesn't have one, he doesn't have one, It's undefined, okay? So that's how Brendan thought you're going to use this language. And there are some good ideas in here, but it's kind of a mess but you got some idea about what JavaScript is actually doing now.

[00:03:57] So the new prefix, if it had been implemented as a method instead of as an operator, this is what it would do. It would create a new object, which inherits from the functions.prototype property. And it will then call the method passing in that object, binding it to this, and getting a result and that result is probably what's gonna get returned.

>> Douglas Crockford: And again, this is kind of a mess, so. But we haven't inherited much yet, so let's reexamine this thinking about inheritance. So if we replace the original prototype object, we can then inherit another object's stuff. So that made no sense. So let's look at an example try to figure this out.

[00:04:51] So we're going to make a Hoozit a Hoozit is something that will inherit from Gizmo, okay? So we've got a Hoozit constructor like before. And we're gonna replace hoozit.prototype with an instance of Gizmo and then we'll add an additional method. We're gonna add a test method to our new prototype.

[00:05:13] And the Java guys looked at this and said what the hell is that? I mean we thought the other one was bad, but holy cow, that's how you write extends. Are you serious? This is just, this is horrible and this is absolutely horrible. So let's diagram it, let's look at what's actually going on here.

[00:05:31] So here's our instance of Hoozit. This is the Gizmo function that we had before in Gizmo.prototype. And it was our Hoozit function in Hoozit.prototype. But we replace Hoozit.prototype with this new instance of Gizmo. So when we add the delegation links. We've got that inheriting from that, which inherits from that, and that will inherit from object.prototype, but I left that one out.

[00:06:04] So if we ask our new instance for its ID, we get it there. If we ask for its test method, no, there it is, we'll return that method. If we ask for it's toString method, go no, no, there it is, we'll return that one. If we ask for it's constructor property, we'll go, no, no, yes.

[00:06:25] Except it's a gizmo, oops,
>> Douglas Crockford: So which I think is not that bad because you should never ask anything what it inherits from. You should only be asking what can you do and we should judge our objects by the character of the contents. So again, it's, that's how it works.

[00:06:48] And one source of confusion is that sometimes we consider this to be the prototype link. But this one is also called .prototype. So having two pointers, which are designated as the prototype pointer, which are completely different. And distinct is certainly a source of confusion as well. But this is how most of the people who are writing the JavaScript are using the language.

[00:07:17] They are doing this and they are miserable, they are hating their lives. And they are hating JavaScript and they're angry and bitter. And wishing that their favorite language was doing better because why have they come to this writing classes in JavaScript. It's just awful. So yeah, so putting them together, it's just there's awful stuff here.

[00:07:45] There is just the head of ugliness and in the lack of soothing syntax. We're not getting enough code reuse. For example, both constructors create an ID property, but they both have to repeat that and that it's not code reuse. So there are lots and lots of JavaScript libraries in the world.

[00:08:04] And most of them recognize that there is something seriously lacking here. And so they'll provide some mechanism for sugarcoating this sort of classical system in order to make it a little bit nicer. For example, they might do something like create a function called new_constructor. And it will make constructor functions.

[00:08:30] And I will pass into it the thing that I want to inherit from. So I want to extend object, I want to extend gizmo. And I'll pass in a constructor function and I'll pass in an object containing the methods that I want the instances to inherit. So it doesn't look like Java, but at least you can recognize the components, right?

[00:08:53] And so there is something nicer about this. And the surprising thing about this function is that that's the entire function. So JavaScript is such an amazingly expressive language, such a powerful language. That one little piece of code can radically transform the appearance of the language, which is pretty extraordinary, not a lot of languages can do that.

[00:09:20] Do I recommend this approach? No I don't, Even though this is clearly better than using the language as intended, you're still stuck in this classical paradigm. Except you're trying to do classical programming in a language without a type system. And that is really really hard. Yeah, that classes provide a lot of brittleness.

[00:09:43] And without the constant type checking to keep you honest, it's really easy for things to go bad. And in JavaScript, things go bad very quickly all the time. And that's why people who are trying to write in this model, in JavaScript, are so angry at the language. They're constantly in a sense of rage.