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

Kyle explains the relationship between __proto__ (dunder-proto) and the prototype keyword and how both reference the underlining prototype. ES5 added a standardized way to do this using the getPrototypeOf method.

Get Unlimited Access Now

Kyle Simpson: Now what about line 17. I start referencing this bizarrely named property underscore underscore proto underscore underscore. Let me just stop right here and say, a couple years ago the JavaScript community was trying to come up with a better name for that. Because no one wants to say underscore underscore proto underscore underscore.

So we came up with a better name for it, kind of like we came up with IIFE. The name for that underscore underscore thing is Dunder, kind of like Dunder Mifflin. So if you want to be a cool kid in javascript, the way to properly pronounce that property name is Dunder Pro.

So that's the third thing that I will say, and keep that distinguished from the other two dot prototypes, is that underscore underscore pro I will pronounce as Dunder pro. Okay? So a1.__proto, is there a __proto property on this guy? No, so what's he going to do? He's going to come up to this object.

Is there a __proto on this guy? No, so he's going to come up to this guy, and it turns out there is in fact a Dunder Proto on the built in object prototype. So when we say a1.__proto, we are calling this property. Turns out it's not actually a property.

Turns out it's a Gedder Function. So it's kind of like making a function call on line 17. Guess what that function call does. It returns the internal prototype linkage of whatever the this binding is. At the call site on line 17, we pretend that there's some parenthesis on line 17.

When that's calling a function, what will the this keyword be inside of that function called?
Speaker 1: A1.
Kyle Simpson: A1. Which is what we want it to be. So it's going to return the internal prototype linkage of A1. So this bracket bracket P is the internal link. We can say that the public link for it is underscore, underscore proto or Dunder Proto.

Kyle Simpson: Everybody following so far? This is a public property that references an internal characteristic. Now, the problem with Dunder proto is that its never been standardized. It was invented 15 years ago by Mozilla because they wanted some way to publicly expose this internal property, but it's never standardized.

Unfortunately, even though it was not standardized, everybody adopted it. Safari, and Chrome, and all the other browsers, they all came out and adopted it. Except for one browser, anybody guess which browser?
Speaker 2: IE.
Kyle Simpson: Internet Explorer said no, no, no, we're not going to put a dunder proto on there, no, no.

In a shocking twist of irony Internet Explorer, Microsoft, who's the king of adding proprietary non-standard stuff to JavaScript said no, no, no. Dunder proto's not standardized. We're not going to add that to the language until it gets standardized. And they could never agree on the TC39 committee how to standardize it, so it became a defacto standard, except for IE.

Which means it wasn't really reliable, because if you had any code that needed to run in IE, you couldn't use it. So there's a lot of people that really hate the Dunder proto, I'm not advocating for or against it, I'm just telling you it exists. But it's non standard, until ES6.

It's finally been standardized. That doesn't mean that you should use it. It just means that they agree that it's finally about time that, if everybody's been using it, we ought to go ahead and standardize it. And guess what happened immediately after TC39 publicly said we're going to standardize it?

IE dropped it into IE 11. So, it exists in IE 11.
Speaker 1: This has been a request from a couple of people in the chat. If we could pause whenever we're done drawing this drawing, and have it on the full screen so that it could be screen captured.

Or if there's-
Kyle Simpson: I don't want to-
Speaker 1: Or if you have a drawing of it online somewhere.
Kyle Simpson: I don't mind it, but I've already said this exact same diagram in a better form comes like three slides from now.
Speaker 1: Okay.
Kyle Simpson: So I'm only drawing out the diagram so you see how it fits with the lines of code.

But I provide you these diagrams in a few slides, so don't worry. ALright so this a1.__proto__ points at this object, and we can see that that's the same thing as foo.prototype, everybody see that? a1.__proto__ is the same thing as foo.prototype and both a1 and a2 point to the same object.

Everybody with me so far?
Kyle Simpson: Okay, moving on to the next slide. Its the same code but I want to illustrate one other thing. This Dunder proto not being standard until, of course, ES 6. Back in the ES 5 days, that was back in like 2009, 2011, they said we do need to provide some standardized way for you to access the internal prototype characteristic.

We're not going to do it with the Dunbar proto, but we need to provide some way to do it. As an ES5, they added a mechanism that you see here on line one, get prototype of Object.getprototypeof, is a utility that will extract the internal prototype characteristic. Okay, so if we ask for the characteristic of a1 it's going to give us this linkage.

So that was added as of es5 which means it was standardised as of es5, which means ie put it in as of ie9. So while you didn't have dunner proto, you did have object.getprototypeof as of ie9. Which is a lot better than IE11, but it still leaves IE8 and below totally out in the cold.

What do we do about IE8 and below. We then come to the third and final way that you can, in a very crappy and hacky way, get at that linkage. And the way that we do that Is what you see in line 18. We can do this really crazy indirect approach.

We can say something like a2.constructor which gets over here to foo, .prototype which gets back here to the objects. So a2.contructor.prototype will also get us to the object. Now, here's the problem with that, both the constructor property and the prototype property are writable properties. They happen to default to point in where we show them here.

But guess what happens if either or both of them gets overwritten? Then that third way of doing it is completely out the window, it's totally non-reliable. They're not special properties in some sense that they're protected or somehow forced to be the right thing. They're just properties and they can be changed.

Okay. But those are our three ways of getting it, we have Dunder proto, which is available as of IE 11 and standardized as a VES6. We have a object I'd get prototype of gets us that same linkage that's available as of IE 9, standardized as of IE 5.

And we have this crappy ES 3 way of doing it, dot constructor dot prototype.

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