Check out a free preview of the full Deep JavaScript Foundations course:
The "Explaining Prototypes, Part 2" Lesson is part of the full, Deep JavaScript Foundations course featured in this preview video. Here's what you'd learn in this lesson:

Kyle explains the relationship between __proto__ (dunder-proto) and the prototype keyword and how both reference the underlining prototype.

Get Unlimited Access Now

Transcript from the "Explaining Prototypes, Part 2" Lesson

[00:00:00]
>> Kyle Simpson: Now, that means that a1 constructor and a2.constructor point at the same location. You'll notice that I'm using this linkage, but I don't have any direct way to say where is a1 linked to? And early on in JavaScript they said that's kind of a gap in functionality. It would be nice for me to ask, given any object, where is it linked to?

[00:00:22] What is its prototype linkage? This by the way, is an internal linkage, it's not accessible from the outside. So how do we get a public way to access that prototype? Well it turns out they added a temporary hack, this __proto thing that we see there on line 17.

[00:00:44] __proto__ is a really long way of saying that property name, and it also doesn't make me sound very cool. So I'm gonna do what the cool kids do, and I'm gonna refer to that as dunder proto. That's just a made up way of pronouncing that property name. So they made up dunder proto, and they said let's make a property that exposes the internal link.

[00:01:07] So if I call a1.__proto__, I get Foo.prototype. That's cool, right? Unfortunately, that dunder proto was not a standard thing so that's why it got named in that weird way. And as soon as they named it in that way and they said, don't use it, this is just a temporary thing until we configure out what it should be called, guess what everybody did?

[00:01:30] They started writing code relying upon it, proving yet again that old adage, there's nothing more permanent than a temporary hack. Cuz as soon as they started using it, it became a permanent part of the platform. You fast forward 18 or 19 years, and they were forced essentially, to finally standardize it.

[00:01:47] So now, as of ES 6, there's a dunder proto in the spec. That is the public property that exposes the internal linkage.
>> Kyle Simpson: For about 15 of those 18 years, there was one browser that didn't wanna play by those same rules, that didn't wanna do the dunder proto even though everybody else did it.

[00:02:10] Can you guess which browser that might have been?
>> Speaker 2: IE?
>> Kyle Simpson: IE, they're like no, no, no we don't wanna add that, it's not standard, which is super hypocritical because they added a bunch of non standard stuff. But they're like no, we don't wanna add dunder proto. Once it was finally added to ES6 they relented and added it.

[00:02:26] So now, as of the latest versions of Edge that are ES6 compliant, you can rely on dunder proto to ask, where does this object link to?
>> Kyle Simpson: Okay? Now in ES5, which was several years ago, back in 2009, they did add a utility. They couldn't agree on dunder proto, but they did add a utility which we see on line 15, Object.getPrototypeOf.

[00:02:50] That is a special utility that can reach into an object and tell you what its internal linkage is. So that's the same thing as calling a1.__proto__. IE did add that, so we have that utility all the way back to IE9. But what about those unfortunate souls that have to support IE6, 7 and 8?

[00:03:12] Well we have the third and final crazy hack, follow with me. If I wanna get from a1 to Foo.prototype, but I don't have dunder proto, and I don't have getPrototypeOf, here's what I can do, a1.constructor.prototype.
>> Kyle Simpson: Yeah it really is as ugly and hacky as it just sounded.

[00:03:36] Let me do that again, a1.contructor.prototype. Now that's the hacky way, back in the day that we figured out where is this thing linked to. The only problem is that .constructor and .prototype, both of those properties are writable. So if either or both of them gets changed, all bets are out the window.

[00:04:02]
>> Kyle Simpson: It's a good thing we finally have a standardized way of figuring out where one object links to another. Now in that understanding, if I call a1.identify, does a1 have an identify?
>> Kyle Simpson: No, so what are we gonna do?
>> Kyle Simpson: We're gonna walk up the prototype chain one link, and we're gonna say, does this object have an identify?

[00:04:29] So we're gonna call that function, now we're gonna be on line 5. What is the this key word on line 5 gonna be pointing at?
>> Kyle Simpson: If my call site says a1.identify, what is the this keyword on line 5 gonna be pointing at?
>> Speaker 2: A1.
>> Kyle Simpson: A1, there's the implicit binding rule.

[00:04:52] You might have wondered why is dynamic function context useful, here's why it's useful. Cuz we can locate functions on different objects and the call site is the thing that decides what its context is. Because if we wanna get the me property off of a1 not the me property that doesn't even exist on Foo prototype.

[00:05:11] So, we call a1.identify, and it just magically works because of the this binding rules.
>> Kyle Simpson: So, now we finally see that this prototype chain is the symmetrical mirror to the lexical scope chain. These are two separate buildings that exist in JavaScript. You can see that when we start at the current scope and we go up the lexical scopes, that's conceptually almost the same as starting at the current this object, and walking up the link of objects in the prototype chain.

[00:05:47] The this and prototype chain is the dynamic form of the lexical scope chain. When I discovered this several years back studying JavaScript, it kinda blew my mind because I realized what a powerful concept that was that nobody was talking about. That we have both of these systems built into the same language, it's the best of both worlds.

[00:06:10] But we haven't been taught to think independently about them, so we haven't known how to fully take advantage of that power.