This course has been updated! We now recommend you take the Deep JavaScript Foundations, v3 course.
Transcript from the "Explaining Prototypes, Part 1" Lesson
[00:00:00]
>> Kyle: So now let's look at some code. And here's where I'm gonna start to diagram some stuff. And don't worry about copying this diagram because this diagram shows up in your slides a little bit later. So don't worry about copying this down. What I wanna do is show you how each line of this code conceptually gets laid out in a diagram way.
[00:00:22] So I'm gonna go line by line through the code and draw it in a diagram form. But don't worry, the finished diagram which will look a lot better than my white boarding skills, that finished diagram is in your slides in a few slides, okay? To first begin to diagram this, I need to address that there's a line 0 environment.
[00:00:39] There's some stuff that exists before our program even runs. And that part I'm going to draw a dotted line and draw some stuff above it. So let me draw a dotted line here across the top, and above this dotted line I want to create the line 0 environment.
[00:00:59] I wanna talk about what exists before our program runs. You remember earlier in the workshop we talked about a capital O Object. And I'm gonna represent functions, I'm sorry a capital O Object function. I'm gonna represent functions as circles in this diagram, so here's this capital O Object function.
[00:01:26]
>> Kyle: That's the capital O Object function. It exists before our program runs. There's another entity that exists.
>> Kyle: I'm gonna represent it as the square or rectangle, whatever you wanna call it, it's an object. It's not a function it's an object. So functions will be circles, objects will be squares/rectangles.
[00:01:49] Now this thing is a really important entity in JavaScript, but it does not have a good name. Like the most important object in all of JavaScript and we don't have a good name for it, so we refer to it,
>> Kyle: Based on the property that links to it.
[00:02:10]
>> Kyle: And in particular, that property is called,
>> Kyle: .prototype.
>> Kyle: There's a property from the Object function to this other object, this really important thing that exists. And because we don't have a good name for it we like to refer to it as object.prototype.
>> Kyle: Now on object.prototype there's a bunch of really useful stuff, stuff we've already seen, like two string and value of and so forth, so there's a bunch of really useful contents on that object.
[00:02:44] It's the most important object in all of JavaScript. But we don't have a good name for it, so we refer to it as object.prototype. Now here's one other entity here, or actually not an entity, but a linkage. It goes in the other direction.
>> Kyle: And that property has a much more confusing name to it.
[00:03:09] Confusing because it's gonna try to convince you that there's something there that isn't. This property is referred to as .constructor.
>> Kyle: Now that property name sure does a really good job of implying that the object was constructed by the function, right? Except it wasn't, it was not constructed by the function, but it sure looks like it was and constructor seems to imply that it was.
[00:03:41] Constructor seems to imply that this function has some kind of special relationship to the thing, like was constructed by. It doesn't, this name constructor here is no more meaningful in a real sense in JavaScript than if they'd called it .foobar.
>> Kyle: But because they called it .constructor, it actually leads people to conclude things that aren't actually true.
[00:04:09] All right, that's our line 0 environment. Now we get to line 1 of our code. We have a foo function, so we're gonna need a circle. So line 1 creates a circle and we label that circle Foo. Line 1 is declared a function and we made it and made a circle.
[00:04:34] In addition, line 1 has done something that's not obvious. It's created another entity.
>> Kyle: It's created an object, it's kind of an important object. We don't really have a good name for it, so you can probably guess where I'm going with this. We're gonna refer to it by the property that points to it.
[00:04:58] There's a property that points from there to there.
>> Kyle: And guess what that property's called?
>> Speaker 2: .prototype.
>> Kyle: .prototype.
>> Kyle: So we don't have a good name for this object, but we just refer to it as foo.prototype. Which is super inconvenient and weird, but let's just go with it, okay?
[00:05:24] There's another thing that was created here.
>> Kyle: A property that points back in the other direction. I bet you can guess what that one's called.
>> Speaker 2: Constructor.
>> Kyle: .constructor. That has also no more meaning to it than if they'd called it .foo bar. Because this object was not constructed by this function even though it sort of implies that's my constructor, okay?
[00:05:59] Yeah.
>> Speaker 2: Does this happen on line 1 or line 8?
>> Kyle: This is all happening on line 1.
>> Speaker 2: So any function, even if it's not a constructor function, just like a regular function, will have an object called prototype?
>> Kyle: Yep, exactly, this is all line 1. As a matter of fact, there's one other thing that line 1 does.
[00:06:25]
>> Kyle: There's a relationship between that object and object.prototype. There's a linkage between foo.prototype and object.prototype, and I haven't fully described what that linkage is, but we'll come back to it.
>> Kyle: So that's line 1. Now we move to line 4. We'll come back to line 2 later. We come to line 4.
[00:06:47] And you'll notice that I just start referencing that arbitrarily named, weirdly named foo.prototype thing. And what I do is I add a property to it called identify. You see that? It actually doesn't matter that it's a function in this case, so I'm just gonna write identify-
>> Kyle: As the contents of that object.
[00:07:11] We've added an identify to it.
>> Kyle: We'll skip over line 5. Let's move to line 8, that's where the fun really starts. Somebody look up in your notes, and read for me item by item, the four things that happen when the new keyword is put in front of a function call.
[00:07:31] Because I'm gonna diagram those four things as they happen. What's the first thing that happens when new is put in front of a function call?
>> Speaker 2: It creates a new object.
>> Kyle: It creates a brand new empty object out of thin air. What's the second thing that happens when new is in front of it?
[00:07:47]
>> Speaker 3: The new object gets linked to [INAUDIBLE].
>> Kyle: It gets linked to. We haven't even described the link yet, but let's draw it in.
>> Kyle: What's the third thing that happens when new is put in front of a function call?
>> Speaker 4: The newly created object is passed into the function call as-
[00:08:08]
>> Kyle: Yes, it's passed into the function as this. So let's invoke the foo function and call as it's this keyword, this newly created object. What do we do on line 2? We're adding a me property to it, right? So we're gonna put a me right here. What's the fourth and final thing that happens when new shows up in front of a function call?
[00:08:37]
>> Speaker 5: This context is implicitly returned.
>> Kyle: Because foo does not return its own object, we assume that you meant to say return this on line 2.5. So that object gets returned back to line 8 and gets assigned the name A1. That's line 8. Does anybody feel roughly comfortable with how I diagrammed line 8?
[00:09:03] So if you know line 8, then I can just draw line 9 out.
>> Kyle: That's line 9. Feeling okay so far? Let's move to line 11. On line 11, I add another property directly to A2. So I'm putting a speak right here.
>> Kyle: Now just looking at the diagram, ignore the code for a minute, looking at this diagram, would you expect on this diagram to be able to say A1.speak?
[00:09:44] Because when I say a2.speak = when I assign something, I'm putting it directly on the object, all right? That's a difference compared to what we're about to see when we look at these linkages. I just wanna point out that assignment here doesn't pay any attention to linkage. It just puts it directly on whatever object you tell it to put it on.
[00:10:04] Okay, there's no relationship between the two. Now if I were to call something like a1.constructor, like I do on line 15, does a1 have a constructor property on it? A lot of people think that the a1 object does in fact have a constructor property. They think of that constructor property as being sort of like a stamp that tells you where the object came from.
[00:10:35] But the diagram clearly shows us that there is no such constructor property on it. So when we call a1.constructor, we first inspect this object to ask if it has a constructor property. When we find out it does not have a constructor property, there is a default behavior built into JavaScript which has been there all along.
[00:10:54] You just might not have ever heard it fully explained. It is called the prototype chain. What it will do is say, okay, you're asking for something that does not exist on this object. So what I'm going to do is follow this linkage, which is called the prototype chain.
[00:11:10] I'm gonna go, do do do do do do do, up to the next object in the chain, and ask to see if it has a constructor property on it. Does it?
>> Kyle: And where does it point? Foo, so we get the outcome that a1.constructor is foo. Sure seems to be like we're suggesting that a1 was constructed by foo, right?
[00:11:38] That's only a happy accident, but we're trying to convince people, hey, this is a class system and this thing was constructed by this other thing. If you squint at it and you don't ask any questions, you might be able to convince yourself of that. But if you start asking some critical questions, you will find out very quickly that that whole house of cards falls apart.
[00:12:01] So it's only a happy accident that a1.constructor points to foo. We'll see that fall apart here in a few slides.