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

Using a code example from the slides, Kyle spends some time diagramming the relationship between an object and its prototype.

Get Unlimited Access Now

Kyle Simpson: Here's one of those places in the code where I'm going to put up this slide, and I'm going to spend an awful lot of time, maybe 30 minutes or more, talking about this slide. And this is the point, by the way, where I need to bring over the white board, because this is my long diagram.

So, what I am going to do is I'm going to draw for you a diagram of what occurs when this code is interpreted by the JavaScript engine. So, I will present this diagram in a few slides, so you don't need to redraw this yourself, but it's instructfull for me to show you how the diagram comes about, based upon each line of this code.

So that's what were going to do here. And what I'm going to before we even get to line one. There's already something that has occurred just as a function of what's happened with the JavaScript language. So I'm going to draw this dotted line here. This dotted line, everything on the top of this dotted line is going to indicate stuff that's already happened before we even get to line one.

And what I'm going to do is I'm going to represent objects as squares and functions as circles, okay? Just in my own convention. So, before we even get to line one of this code, there is a function, which I'll represent with a big circle, there is a function who is called Object.

Capital O, Object. And you're probably familiar with that, that exists in the language. So there's a function called Object. And there is an object, there is a square, there is an object, who this guy is linked to. And this guy doesn't really have a name, he just has this kind of weird, arbitrary label.

The arbitrary label that he is object.prototype, all lowercase. So object.prototype points at this object, okay? Now on this guy is stuff like two string.
Kyle Simpson: And value of and several of the other things that you're probably already familiar with that are built in the language but they all come from this guy.

Everybody with me so far? This exists as, at the beginning of every JavaScript program, it's part of the environment that gets created. Now let's talk about line one. What is line one going to create for us? Well line one, I'll come over here, line one is going to create a circle that we give the label Foo.

It's a function called Foo. It's also going to create an object that we are linked to. And it's going to have that same arbitrary name, .prototype. All lowercase letters, .prototype. In addition to there being this connection, there is also a connection in the opposite direction. This object has a property on him called .constructor.

Kyle Simpson: Now, most people see the property name .constructor and they immediately think that .constructor means was constructed by. In other words, this object was constructed by this function. Not true. It's one of those many misconceptions you're going to have to set aside. The word constructor is literally just an arbitrary word.

It could've been abracadabra. It doesn't actually mean anything at all about was constructed by. So you just have to kind of set aside that idea. But there is this dual linkage here. There is a .prototype that points to this object here.
Kyle Simpson: And there's a constructor linkage back to the Foo function.

That's everything that we get as of line one. Everybody with me so far? Now we're going to skip over line two for now, we'll come back to that. What happens with line four? You'll notice that we arbitrarily start adding properties to this arbitrarily named object, Foo.prototype, it's this guy that's just hanging out here, we start adding properties to him.

So we add and identify and that's like doing this, it's like adding identify.
Kyle Simpson: We put identify directly on the object. It doesn't matter that he's a method right now, he's just a property for all we care. So we're putting identify directly on the object. Now, let's skip over line five, we'll come back to that.

Let's do line eight. Line eight says new Foo. Okay, remember I said there were four things that happened when the new key words gets called with a function call. Anybody remember what those four things were.
Speaker 1: Brand new objects get created.
Kyle Simpson: Brand new object gets created and I'm going to create a brand new object, okay.

Brand new object gets created, what's the second thing that occurs?
Speaker 1: Object gets linked on.
Kyle Simpson: Object gets linked, so there's a link that occurs here which I'll explain in a moment. What's the third thing that occurs?
Speaker 2: There's this, the context.
Kyle Simpson: The context gets set to the this.

So when we are calling the Foo function of this keyword will be pointing at this particular object. Sorry for my poor drawing skills. So when we execute line two and we say this.me, when we add a property to me, we're putting a property directly onto this object. Does everybody see that.

Doesn't matter what it's value is, we just put a property on it. What's the fourth thing that happens when we call the new function.
Speaker 2: Returns this?
Kyle Simpson: It returns this, which then on line one, we assign to a1. So we give the label to that object, a1.

Does everybody follow how line eight occurred? You notice that we haven't talked about classes, or inheritance, or substantiation, or anything, because none of that stuff actually exists. You've just been lied to that it exists. Okay, line nine. If we understand how line eight works, then line nine does the exact same thing.

So it's creates another box that's also linked, that also gets a me property, and we give him the label, a2. Did everybody see that?
Kyle Simpson: Now, let's look at line 11. Line 11 says a2.speak. So where does that speak property get added?
Speaker 2: On a2.
Kyle Simpson: Right here.

Kyle Simpson: Everybody follow that? Now at this point if I were to say something like a1.speak, what would you expect to happen.
Kyle Simpson: It's not there right, because it's quite clear that it's on a2. We're going to see how a1 and a2 can reference identify. But for right now, it's very clear that a2 got a member directly on him on speak, it wasn't added to anything in this prototype, okay?

So, let's look at line 15. Says that there's an a1.constructor. Look at this object and tell me if you see a constructor property on it.
Speaker 3: Comes from the prototype.
Kyle Simpson: There is no constructor property on this object. I would say better than 99% of all JavaScript developers think that there's a hidden constructor property on the object.

Just because it's automatically created by, because it was constructed by Foo, therefore it must have a constructor property.
Speaker 2: Higher up on the It doesn't have it.
Kyle Simpson: So, when we say a1.constructor and it doesn't exist, what happens?
Speaker 2: It creates one.
Speaker 3: It goes up the prototype chain until it finds it.

Kyle Simpson: It's going to go up the prototype chain. This is where this prototype mechanism starts to look a lot like a scope model, and it's the whole reason I set up that comparison between the two models. Because what we're going to do is we're going to say, a1.constructor does not exist.

We're then going to traverse the prototype chain. These linkages that I talked about, these are called the prototype link. So in the spec speak, prototype is referenced by saying [[Prototype]].
Kyle Simpson: Then you can see quite right away why that's confusing because they call it [[Prototype]] and they call this thing .prototype and grammatically it's hard for you to tell which one I'm talking about.

So I'm going to distinguish verbally when I say these things by saying [[P]] or .prototype. That's how I'm going to distinguish between the two so you know what I'm talking about. So these linkages here are called [[P]].
Kyle Simpson: They are internal linkages. They don't exist publicly. They're just an internal link between the two and this is a prototype chain that we can traverse.

So when we say a1.constructor, there is no constructor, so we walk up the prototype chain and we ask for this guy, does this guy have a constructor? Yes. So we can say .constructor and point over here. And by the way, let me pause for just a moment, I forgot to draw something earlier.

You remember on line one when I was drawing this, I forgot something. There is a linkage from there to there. And that linkage is also [[P]]. That happened as of line one, I forgot to draw it in, okay? So we have these [[P]], so when I say a1.constructor, I'm delegating up to this guys who does have a constructor and he ends up being Foo.

At this point, you would be forgiven if you were under this misconception that a1.constructor pointing at Foo means Foo was the one who constructed me. because that's kind of a misconception. Actually a lot of a misconception, .constructor doesn't mean I was constructed by. It just happens as a happy accident to point to the proper, or the location that we would want it to point to here.

We'll see in just a few slides why that assumption goes completely away under other circumstances. So a1.constructor points to Foo. Clearly a2.constructor will point to Foo. Everything feels good.

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