Transcript from the "Exercise 5: Solution" Lesson
>> Justin Meyer: All right so I'm gonna go through the answer to INSTANCEOF. This is our last exercise for this kind of stuff. It actually gets mostly, almost all, easier than what we just did for the end of, for the rest of today and for tomorrow. So we were just doing instance of, we wanted to be able to say, hey is p an instance of person or is p an instance of object, instance of person or instance of object.
[00:00:34] And the way to do this is start with p. And just check when, or person, check when it's proto property points to the constructor function's prototype. So I'll just check. Okay, is person.proto equal to person.prototype, p.proto equal to person.prototype. If I were doing for object, I would first check that.
[00:01:00] And then I would walk up again to this, this is a proto, the proto again, to see if it's equal to object.prototype. So let's see this in action. So the first thing I'm gonna do is just check if objects
>> Justin Meyer: .__proto is equal to constructor.prototype.
>> Justin Meyer: All right, and if it is, I wanna return true.
[00:01:34] So this would work if I was doing something like instance of p and person. All right, cuz I'm just gonna, again, check p proto is that equal to person.prototype, return true. Now I wanna make it work. So if I do, is p an instance of object. So to do that, I'm gonna use a little bit of recursion.
[00:02:07] I'm only gonna do it if there is a proto property, to make sure that I haven't gotten to the, I didn't draw the proto of this guy but he is, it would be no.
>> Justin Meyer: If there is a object proto, I'm just gonna return the result of instance of pass at the object proto, and pass at the constructor function.
[00:02:43] And finally I'll just do an else, cuz that means we've gotten to the very top. And return false. Any questions about this?
>> Justin Meyer: Cool. All right so I'm gonna do kind of a little high level overview, but try to do it from a different way of just this kinda, the dot operator, proto property, and the prototype.
[00:03:42] Equal's an operator and the dot is an operator, right? These things are part of the language that do something given some data. The dot operator you've all probably seen it used in this fashion, over, over and over again. But you could also do something like this, I can create an object with a proto property that points to another object with a name property that is bar.
[00:04:09] I could just, and then if I were to write object.name, this would give me bar. This is all that the dot operator is doing. It is just saying, look at on the current object for a name property, if it doesn’t exist, look if it has a prototype, a proto property, look there for the name property.
[00:04:34] And I could just go as deep as I wanted. I could just keep going. Proto,
>> Justin Meyer: And then put in the name property, and I would still get bar. Now one thing you don't wanna do and [LAUGH] they'll actually warn you if you're doing it, if I were to do something like this, object.proto.proto is equal to object.
[00:05:04] I don't know if which level of proto I'm at there, but if I were to make a cycle with protos and try to look up a property, I think browsers, these used to crash browsers if you try to read the property. But now, I think, most of them detect cycles and will not let you, will throw an error if you try to do this.
[00:05:20] But just to show, it's just, there's just this magic property. And it, the .operator just follows it. That's as simple as it is. You might be, the next question might be, why? Why does it do this? Why is there this special proto property that works with these dot operators, to make this crazy magic happen?
[00:05:43] The reason is, is because we like, as humans, typically object oriented programming. I wanna be able to create a animal and I wanna be able call eats on it. And I might want to be able to create a million animals and be able call eats on all of them.
[00:06:01] But I don't want to manually assign an eats function on every single time a new animal instance is called, right? So what I mean is, I could theoretically, create an animal kind of like this. I could create makeAnimal function.
>> Justin Meyer: And that could take the name of the animal.
[00:06:25] And I could do something like this, return, I gonna do var animal. Make an object with a name as the name, and then I'm just assign it's function.
>> Justin Meyer: Now if I were to call this makeAnimal.
>> Justin Meyer: Let me put some semicolon, so it doesn't look like I'm doing stuff horribly wrong.
[00:06:58] If I were to call this makeAnimal and make an animal, this animal would behave just like the other animal objects that we were kinda showing created with the new, if I was doing new animal. So I could do animal that eats, and that would give me eating food or something like that.
[00:07:27] But who can kinda see the problem here? Kinda already mentioned it's performance related. The performance problem is that every time makeAnimal is called, it's got a sign, an eats function. In this case, it's actually recreating a function every single time. Of course, we could improve that by doing something like animalEats and saving the function.
[00:07:54] So we're not recreating the function every time, but we're still setting a property every single time. And this problem would just get worse and worse as we added more properties. Eats, speaks, so this might be some other function that we might have defined up here, right? As we keep adding functions, we have to assign more and more properties every time we want to make an animal.
[00:08:24] What the proto allows us to do, is look on directly on our object first but then look somewhere else for potentially shared properties. And when you create a new animal instance, as you already saw, it only assigns one proto property. There's only one property assignment, instead of a property assignment for every single function you want on your instance, your little objects that you want to create.
[00:08:54] So what I mean is, if I have an animal.
>> Justin Meyer: As a function. That does the same kinda thing, just it's just gonna do the this.name equals name thing. And I had the same animal that prototype.eats as a function. And then I also had a speaks.
>> Justin Meyer: Okay, so instead of calling makeAnimal, if I were to do animal equals new Animal, what this does is it creates a new animal instance in memory, which is pretty much what this is doing in assigning its name property to name.
[00:09:48] But instead of having to go through and assign an eats property and a speaks property, it just assigns one proto property to animal, that prototype. And because the dot operator is already wired up to look on the proto chain for these methods, it will find it. And this way I can create lots and lots of objects very quickly, doing very minimal work and delay the and, essentially, delay the cost.
[00:10:22] Because essentially what we're saying is, look up is going to be a tiny bit more expensive for animal dot, this kind of animal that eats, versus this kind of animal dot eats, because there's a walk up the protochain. But we're making that trade, because creating a million of them is gonna be so much faster.
[00:10:40] So that's why there's this proto thing and why it walks up and tries to find these shared properties. It's cuz you don't want to make every object have a copy of every single property. It's a performance thing. Hopefully that gives you some better context and understanding of why it is this way.