Transcript from the "Prototype Linkages" Lesson
>> Kyle Simpson: Now, let me throw a wrench into the mix. What happens if I were to add and identify right here? And then I called a1 that identify. Where is it gonna find it?
>> Speaker 2: One a1.
>> Kyle Simpson: It's gonna find it right here. So we're gonna be calling line 13.
[00:00:17] What is the disk key we're gonna be pointing at on line 13?
>> Speaker 3: A1.
>> Kyle Simpson: Still a1, do you see the problem? We're gonna have this like circular recursion thing where we keep calling this thing. Because we want to like class oriented coding, relatively polymorphically refer to that one.
[00:00:35] But because we are using this keyword, it's just gonna infinitely recurse on itself. So what do you think we should do to get from this function to that function?
>> Kyle Simpson: Well, we could try calling the, this.__proto__.identify, right? We could say this.__proto__.identify, but there's a problem here. That isn't gonna work.
[00:01:03] It's not gonna print out the a1. Can you spot why?
>> Speaker 2: Of this context.
>> Kyle Simpson: This context. When we call that identify up on line 6, what is the keyboard gonna point at?
>> Speaker 2: On the proto.
>> Kyle Simpson: It's gonna point at the Foo.prototype object, not at a1. So that's not gonna work we can't say this._.proto.identify we'd actually have to say this._proto.identify.call(this).
[00:01:34] Which sucks. But there's a bigger reason why it sucks, because we use 1_proto there. But guess what happens if someday later, we come along and we add another X object into the chain, and then we call X.identify. Does X have been identify?
>> Kyle Simpson: So where we gonna go?
>> Speaker 2: A1 [INAUDIBLE]
>> Kyle Simpson: Here. Now, we gonna recalling that identify function the line 14, if you will. What is this keyword, we're gonna be pointing at on line 14?
>> Speaker 2: X.
>> Kyle Simpson: X, so we're gonna go X dubbed under proto and get right back to here and have our infinite recursion.
[00:02:11] How many dunder protos do we need now?
>> Speaker 2: Two.
>> Kyle Simpson: We need two. If you add another object now, you need three. So every time you extend your inheritance chain, you're gonna have to go back and fix all those references and add more dunder protos. But that's not even the worst part.
[00:02:29] Let's say we did change that line 14 to have dunder protos in it? Then you call a1.dunder.identify, what's gonna happen?
>> Speaker 2: It's gonna break.
>> Kyle Simpson: It's gonna go from here to here, and then from here to here, does this one have an identifier? Not gonna work. The point I'm trying to make is it's impossible to know how many dunder protos you need.
[00:02:51] Because the this and dunder proto system is not relative, the way class-oriented coding gives us relative polymorphism That mechanism is not relative, it's always absolute to the bottom of the chain. So you can't do relative polymorphism. You can override a function which is what you do in polymorphism.
[00:03:10] You make a child class with the method and you override it, and call it super, you don't have that with the prototype system. So you know what you end up having to do to make a reliable reference? You have to skip the prototype chain entirely and just do it like that.
[00:03:26] Foo.prototype.identify.call(this) which completely skips out on the whole prototype chain and totally shoots all the dynamism in the foot. I have a term for that foo.prototype.identify.call(this) which is such a mouthful. Mostly, I just made this term up to make myself feel smarter. Here's the term, explicit pseudopolymorphism. I just felt I sound smart when I say it, don't I?
[00:03:58] That's trademark by the way, don't steal that, explicit pseudopolymorphism. Because it's not really polymorphic, it's not using the prototype chain. And we have to explicitly tell it which method to call, we can't relatively figure it out.
>> Kyle Simpson: Take away here is, you opt into this problems. These problems of explicit pseudopolymorphism when you choose to do shadowing.
[00:04:25] Because you called identify and identify, you opt into that problem. Now, you might just say, well, that's cool, I just won't opt into that problem, I just won't shadow. I agree, you should not shadow. But if you don't shadow, you lose one of the most important parts of all of class oriented design, which is method overwriting and polymorphism.
>> Kyle Simpson: In clustering to design they tell you make a method in the child class override it, call the base parent was super, you lose that if you do shadowing.
>> Kyle Simpson: So maybe this system is great, but maybe it's not so great at representing classes.
>> Kyle Simpson: On the other hand, if we have methods of different names, like I have here, I have both a speak and an identify.
[00:05:18] If I say this.identify on line 11, what is the this key we're gonna point at?
>> Speaker 2: A1.
>> Kyle Simpson: A1, so I started out at A1.speak on line 16, went up to find speak on the prototype, then I came back to A1. And now, I walk back up and find it on identify, and what's the this keyword on line 6 gonna point at?
>> Speaker 2: A1.
>> Kyle Simpson: Still a1. No matter how many times I have to walk up to prototype chain, and no matter how far up the prototype chain I need to look. We always stay rooted at the call sign, which is the object that we care about. I call this super unicorn magic.
[00:05:57] It's a beautifully designed system. It only falls apart when you're try to do shadowing, aka, when you try to put classes on top of it. It's a great system, it's just not a great class system.