
JavaScript: The Hard Parts OOP Exercise, Part 5
This course has been updated! We now recommend you take the JavaScript: The Hard Parts, v2 course.
Transcript from the "OOP Exercise, Part 5" Lesson
[00:00:00]
>> Will Sentance: We're going to walk through this line by line. Here it is, the pretty final version. We're going to walk through it line by line, this is it. The final solution four is just a pretty little wrapper of this. There's no change really. This is essentially our last hard piece of JavaScript the hard parts we are almost there.
[00:00:19] Lindsey, what are we doing in a second, just still very slowly Lindsay, what are we doing Lindsay?
>> Lindsay: Line one.
>> Will Sentance: Very slowly Lindsay.
>> Lindsay: We are going to.
>> Will Sentance: Good, that's slowly. All you can save fast an repeat a few times, whichever you want.
>> Lindsay: Declare [LAUGH], function.
[00:00:42]
>> Will Sentance: Perfect, you are really praying a lot. Declare function?
>> Lindsay: Call user.
>> Will Sentance: Call user, great, call user. So now, guys, before we renamed it User, it's the user creator function. Let me be really clear, this function has not changed. I renamed it user because that's the standard best practice.
[00:01:06] I don't love this. This looks now, but this is exactly the same as user creator. It's, this function, when we said Here we're getting rid of a bunch of stuff. I've also changed the name now to User. We'll talk about why it's got uppercase for the first letter in a second, but this function could equally be called UserCreator.
[00:01:29] It's job is gonna be to create users, just as we did before. But when it gets run.
>> Will Sentance: Actually you know what? The point that I want, I want to actually live edit that, I think. Because.
>> Will Sentance: There you go. I want to live edit that because I think it is.
[00:01:52] We'll go back in a second and change it back, but for now, let's rename this userCreator throughout. Just so that we do not lose sight of the fact that this is just a function that is creating users. People typically don't name them like that. We'll see what they actually do, but there we go.
[00:02:12] Let's not lose sight of this. All right, I'm one, Lindsay, let's do it again.
>> Lindsay: We're gonna declare a function and name it User Creator.
>> Will Sentance: User Creator, perfect. User Creator. All right, next line, Art.
>> Art: I'm gonna take the userCreator and [CROSSTALK].
>> Will Sentance: This is so hard.
[00:02:36] Sorry, I gave you the toughest question here. Just be really clear, by the way, is this userCreator function at the top here a special type of function? I mean, it needs to be treated in a special way but it is any old function. It's just a regular function.
[00:02:49] There it is stored in memory. Okay, now I gave out a tough one here. The next line says, userCreator dot prototype dot increment. What the hell does that even mean. Well, userCreator is a function. What else is userCreator, Katie?
>> Katie: An object.
>> Will Sentance: An object. So in it's object version of itself so to speak.
[00:03:10] What are we adding, Art? Or what are we referring to? You've got user creator in it's object version. That object has by the way automatically, all functions have this, a property on it for prototype. Which is automatically and object. So what in that second line that we interpret KD are we adding to that prototype object?
[00:03:38]
>> Katie: We're adding a property called increment.
>> Will Sentance: Spot on, there it is, increment, which is?
>> Katie: Which is a function.
>> Will Sentance: A whole function definition. One that we hope any objects that were to get returned out of running userCreator would have access to this guy here. Griffin, what's the next line telling us to do?
[00:03:59]
>> Griffin: Go into the userCreator object.
>> Will Sentance: Yep.
>> Griffin: And then go into the prototype object.
>> Will Sentance: Yes, property on it, which is itself an object, yeah. And what?
>> Griffin: Add the label log in that is a function.
>> Will Sentance: Very nice. I really like how Griffin was really precise there.
[00:04:17] Was it standard. Who knows? It was very precise. There we are. User creator has a property prototype, which is an object in it's own right with the property log in that we just added and associated the function value with the property, the method log in. Ok now Mohammed next line.
[00:04:42]
>> Mohammed: We're creating a variable called user one, and
>> Will Sentance: Why do I always ask so many people the same thing. Yeah Good and we don't know what it's gonna be yet, do we? By the way, let me be really clear. JavaScript at this point isn't going, I tee myself up for an object.
[00:04:57] It does not know what's gonna be stored there yet, it has no idea. In my optimizer, to be honest, particular Java engines do smart things to optimize what they do, but It is, for now, an undefined. We do not know what's gonna be returned. Okay, so now, what happens in that line?
[00:05:17] Let's do it all together, because we've missed out doing this for a few times. We're gonna call the function user creator, and create, together, a brand new.
>> Group: Excecution context.
>> Will Sentance: Beautiful. So there on the bottom is global. We're always in global's execution context, and we add the userCreator execution context with Eva is, Eva and 9.
[00:05:41] Okay, new execution context for userCreator. There it is with Eva and 9. So we're running the userCreator functionality, and we say whatever gets returned out of running this function is going to be assigned where, Katie?
>> Katie: To the variable user1.
>> Will Sentance: Perfect, user1. So let's create a big old execution context for this.
[00:06:10] There it is. We've got execution context in which we have our local memory where anything that gets declared inside this function gets stored. All right, and we know that whatever is gonna be returned out of this function call, whatever gets returned out Will be stored in the user one label in the global execution context memory.
[00:06:35] Good, okay, but we round this function all importantly with something very special in front of it, didn't we? I'm gonna do it in red so that we can know we're dealing with it the whole time. You ran it with this Showed him, I think that's nicer. There we go.
[00:06:56] With this new keyword infront. Now is that new keyword gonna do stuff in here automatically for us?
>> Group: Yes, yes.
>> Will Sentance: Yes, exactly. What's the very first thing it's gonna do automatically inside for us? Who wants to give it a shot? Griffin, what's the very first thing the new keyword's gonna do automatically inside of here?
[00:07:21] What's it say? What's it gonna do automatically for us, the first thing?
>> Griffin: Create an empty object?
>> Will Sentance: Create an empty object. And assign the object to what Label.
>> Griffin: This.
>> Will Sentance: Exactly, it's gonna say, this is an empty object. That we've already done. Before that, what's our standard thing we do?
[00:07:53] When we enter our execution context, Andrew, what's the first thing we fill in? What's the first thing we put in, Mohammed?
>> Mohammed: The parameters.
>> Will Sentance: Parameters, so what are they?
>> Mohammed: Eva and 9.
>> Will Sentance: So name is what?
>> Mohammed: Eva.
>> Will Sentance: Yeah, and score is
>> Mohammed: 9.
>> Will Sentance: 9, okay.
[00:08:15] So those are the regular things we do, and we start like Eva is filled in name. 9 is filled in score, but in the first line there, in before this .name, this is going to be set to, an empty object that's been made for us by JavaScript. We didn't say create an empty object, well we did, only by using the new keyword.
[00:08:35] Inside, under there, you'll hear people say the function's context, has been set to an empty object. People often refer to this as, the context. I don't like that. This is our execution context. This is our context. I don't love that. It's very ambiguous, confusing terminology. But yeah, the this keyword has been set to an empty object.
[00:08:58] All right, is that all that we automated at this stage? Lindsey, do we automate anything else? Okay, do you want to give it a shot?
>> Lindsay: Did we also automate the bond?
>> Will Sentance: We did.
>> Lindsay: Between that empty object and the object?
>> Will Sentance: The user creator.prototype object? I see, whenever we create any md-object, yeah but this one we're gonna set, actually, the bond is gonna be made.
[00:09:27] Do you remember when we made to function store? And we said all these objects is when they get returned out. So this gets returned out to User 1. This object with new user, this used to be called user manually set this would be New User, and we used to manually set this to be to let user function store.
[00:09:41] Which was a collection of functions, now we don't get to do that manually so instead what do we use? We use the fact that JavaScript has this special prototype per object stored on its function here. And by default this Is gonna link, this underscore proto underscore is going to link to usercreator.prototype, which is just, look at that, just this object.
[00:10:20] And just like before, our object that we're gonna return now, and store in user one. What's our overall goal? To write user1.increment, and call it that when we don't find on user1 itself. If we don't find on this one itself an increment property, somehow we're gonna look up through a chain to an object in which we have the increment function.
[00:10:46] And what do you know? We can do that, because we're declaring this object in by automatically with a keyword this, and it's also getting automatically a bond to the function that's being called, name.prototype, which is where that object is stored. But just because we use what keyword, Griffin?
[00:11:09]
>> Griffin: New.
>> Will Sentance: The new keyword, exactly. All right, so we've done a ton of automation already. We haven't had to write a single line of code in here, but now we do. Cuz now we gotta do the property setting. So, at this point lets have Shelby, we hit the body of the function at last.
[00:11:30] All this was automated before we even hit the body of the function. So in we go to the body of function now. Whats it say? This.name equals name. Well what do we look for first Shelby?
>> Shelby: The parameter?
>> Will Sentance: Well we done have parameter. I see what you're saying.
[00:11:43] Let's do the left hand side first. What is this at this point?
>> Will Sentance: Griffin what is this at this point?
>> Griffin: That would be user1?
>> Will Sentance: User1? No.
>> Katie: Empty object.
>> Will Sentance: It's an empty object, it's user1. That empty object is gonna become user1 only when we return out of user creator.
[00:12:02] So, you're right it's gonna be user one. This object is gonna be returned out, we go back to global it's gonna be stored in user1, but right now user1 doesn't even know what's happening in here. User1 doesn't care what's happening in here, until we return out, okay? So as you said Katie?
[00:12:17]
>> Katie: This refers to an empty object so-
>> Will Sentance: And what do we stick into that empty object?
>> Katie: The property name?
>> Will Sentance: Perfect, the property name to what value?
>> Katie: Input name which is Eva.
>> Will Sentance: There it is. Which is Eva and what is the next line tell us to do?
[00:12:36] This.score.
>> Katie: So we add score as a property to the this object instead of equal to nine.
>> Will Sentance: Very good job, very good job Katie. And now, what's our final thing that gets automated before we had to return stuff out manually, what's that final thing that gets automated inside there?
[00:12:52] Lindsay, before we have to manually return this object out, how do we get the object out now? Art?
>> Art: Do the prototype of the bond,
>> Will Sentance: How do we get that object out? Andrea?
>> Andrea: It's just automatic we don't have to hit return.
>> Will Sentance: We don't have to write return at all, it's automatically returned out.
[00:13:12] There it is. I'm doing it in pink to show that it's the automatic. So everything in pink is done automatically for us. It's automatically returning out that this. You can basically imagine inside of here. This is what JavaScript does. It goes, we can write this ourselves, but it goes, this equals object.create so create now the object, object.create, and parse in, object.create and parse in, go ahead Katie.
[00:13:44]
>> Katie: User creator?
>> Will Sentance: User creator, but not the whole thing. Because user creator, the whole thing, its only property is prototype. So it's usercreator.prototype, which is this little baby object, or not a baby object, it's a big old object here with all those functions we just stored on it, usercreated.prototype.increment, increment is the label of that function, login is the label of that function stored in this object within an object.
[00:14:13] So, usercreated is itself an object, inside of it, it had a property object, a prototype, which in itself an object. That's the object that we're making the bond for this too. So this is the first bit as automated, and the end bit, and then we do our manual stuff.
[00:14:28] We do this.name = Eva, and this.score = 9. And then again, more automated stuff. Return what, Katie?
>> Katie: Return this.
>> Will Sentance: Return this. We don't have to write any of this stuff in pink, it's all done for us. All we have to do is this stuff, but let's be clear, Man.
[00:14:58] Do we now see what's going on behind the new key word? A lot of stuff's going on behind the new key word. Do you now see why this is senior developer's favorite interview question to ask? Or VP' s to ask senior developers? This level of sophistication allows us, we'll see in a second, to write far better Object oriented code in JavaScript.
[00:15:19] So, you return out that object, out it comes, and what's in it? But of course, only name, which is Eva, and score, which is 9. Out of return, but of course, it also has its little Bonus_proto_, which is pointing to where, Griffin?
>> Griffin: To the userCreator.
>> Will Sentance: .prootype object.
[00:15:48] Here's our object of interest. There it is, that guy there. So now there it is, user 1. He's no longer undefined. We returned out the object from running Use a creator with a new keyword in front of it and say whatever comes out store in what, Katie?
>> Katie: In user1?
[00:16:05]
>> Will Sentance: There it is, stored in user1. Lets just write it in in our global memory. We have name is Eva, score is 9. And under the hood a little bond. I should use the green. A little bond proto is bonded to userCreator.prototype, which is this guy here. There it is, meaning now we do our all-important check.
[00:16:41] Final line there. Andrea, I'm looking at you. Andrea, what does JavaScript do went it sees user1? Where's it go looking?
>> Andrea: It's gonna go look-
>> Will Sentance: We're in the global execution context now, so where does it go look for user1?
>> Andrea: In the global.
>> Will Sentance: Off it goes.
[00:17:00] Does it find it?
>> Andrea: Yes.
>> Will Sentance: Yes, hooray. Now that's not done yet is it?
>> Andrea: No.
>> Will Sentance: It's got this property, increment. Now is it gonna be successful looking here? All this work for nothing. Do we actually panic, Andrew?
>> Andrew: No.
>> Will Sentance: No, we don't. Because this object,
[00:17:26]
>> Will Sentance: When it was created under its author name, this, got a special bond to userCreator.protoype, which is an object full of functions. So when I don't find increment on user1, where do I go looking, Andrea?
>> Andrea: It's gonna have that preference, proto, and it's gonna look at the protoype.
[00:17:49]
>> Will Sentance: I wanna repeat, it's gonna have that proto_proto_, which is a reference to this userCreater.prototype location. Very well put, Andrea. And what does it find up there, Andrea?
>> Andrea: It finds the increment.
>> Will Sentance: And there it is, it finds the increment of a function. It can use that functionality to make an execution context.
[00:18:08] There is is, a new execution context. Let's just make sure we know what's gonna happen in here. We push this guy now, cuz we have the functionality now, we've found it. We've successfully found the function, no problem. It wasn't on user1, directly. It was on user1's _proto_ reference, from when user1 was born as this, inside the call to user a creator.
[00:18:30] And in we go, and the first line probably says this.score++, right? Okay, and so what's the first thing we do in our local execution context local memory?
>> Will Sentance: Cuz we don't have a this yet, do we, so what's the this set to?
>> Andrea: It assigns it to user1.
[00:18:48]
>> Will Sentance: Exactly, whatever's left of the dot, which is user1. And so this line here basically becomes user1.score++. And where do we look for user1 first?
>> Andrea: In the local.
>> Will Sentance: And do we find it there? Where do we go? Global, and what do we find? Probably score. What do we do with it?
[00:19:12]
>> Andrea: We increment it 1.
>> Will Sentance: To 10. All right, we have achieved our fundamental goal. And look at how much less code we've written. But also, man, look at how much was going on automatically for us behind the scenes. When we used that new key word, we did all of this stuff here and more because we had to do some automated stuff.
[00:19:41] And it's all now explicit. Now I will say this, now do you see why I get nervous saying, we look in user1's prototype? I see, okay, it's called prototype, that object full of functions. But to get to that bit we go to its proto property, which is a reference to an object.
[00:20:06] We don't care it's called prototype, really. It's this object we care about, full of functions. It just happens to be stored in userCreator.prototype. So let's distinguish very clearly, _proto_ is the property on the individual object in which we returned out. If we did a new user2, if we had run userCreator all over again, created a user2,
[00:20:31]
>> Will Sentance: Created a user2, it would have a new name. Let's say name, I don't know. Say name Art and score 12. It too would have an _proto with a bond to this guy up here. If user2 had been created by the line of code, user two = new user and it called userCreator with Art and 12.
[00:21:07] That would have made user2. This object with its own proto bond up to this shared function store that we just only use this shared function store, cuz JavaScript needs a default place to know. Cuz we don't get when we create the object using the new keyword, we don't get to set this automatically for ourselves, manually.
[00:21:26] So we can't call it a nice name like userFunctionStore and objectFullOfFunctions. We need to have a default place to put all the functions we want each of these objects have access to. And the default place is just the name of the constructing object's function.prototype. And it's this object.