
JavaScript: The Hard Parts OOP Exercise, Part 4
This course has been updated! We now recommend you take the JavaScript: The Hard Parts, v2 course.
Transcript from the "OOP Exercise, Part 4" Lesson
[00:00:00]
>> Line one is declaring a function user creator. I imagine, is that right?
>> Yes.
>> Okay who shall I call upon? Bob do the honors for us. Line one what's it say?
>> Declare user, creator function.
>> Great. Store it as the whole Function definition. Thank you, Bob.
[00:00:23] Line two. Muhammad.
>> Creates a variable called user function store.
>> User function store. Yup, and it is?
>> Has a value of two functions. Well, what is it?
>> A variable.
>> Object.
>> It's an object, isn't it?
>> Yep?
>> Do you see that? Right, it's not got the value of two functions, it's got the value of an object.
[00:00:49] Do you see you've got these curly braces with two? Yeah, they're not properties of name, score, name3, score2, but these are still just known as object. But it's got two functions stored in it, does that make sense? What's the first property in this object Muhammad?
>> In this object, increment.
[00:01:07]
>> Increment, that's our first property. There it is, increment. And increment is what Muhammad?
>> It is a function.
>> It's a function. Spot on. There it is. What's our second property in this object Andrea? [INAUDIBLE] it's gonna be new user name. Or sorry.
>> What?
>> Sorry.
[00:01:28]
>> So we've got user function stores an object.
>> It's gonna be-
>> With increment as an object on it.
>> It's gonna be
>> I'm sorry, a function on it. Login, got it.
>> Yep.
>> Login is the second property
>> So do you see we've got user function store with increment is the first property, and log in as the second one.
[00:01:47] It's a whole function we put it all in one line, we can put it on two lines. But it's that's the whole function definition stored under log in. Ok that's the whole functionality of log in. Does that make sense Andrea? Great. Next line Andrea.
>> Then we are going to go to,
[00:02:03]
>> Left hand side first.
>> Declere user.
>> Declare user 1, good, and what is going to be assigned to it? Who knows? It's going to be. The return value of calling user creator, the returned out, return whatever comes out, do we have an instinct what that might be?
[00:02:24] Where do think it's gonna be, Mohammed, some sort of?
>> Object.
>> Yeah, some sort of object, exactly, that's what we think but we don't know that yet, right now it's gonna be undefined, we don't actually know what's gonna be stored there, so we have to go.
>> And call userCreator.
[00:02:41] When we call userCreator, we create a new execution context for the call to userCreator. Here it is, our new execution context. There it is. Okay Let's make it bigger. It's slightly bigger. Let's make it wider, that's fair, wider. Not bigger, but wider. There's our execution context. We push the call to userCreator to the call stack.
[00:03:29] userCreator ("Will", 3). Everyone see me grab the board? Stabilizing myself. No, it's because the board shakes when I write on it. Calling user creator in I go. What's the first thing inside of, these pens get knocked down so fast. What's the first thing inside of there Mohammed, inside of the call.
[00:03:57] To user creator. Mohammed?
>> We pass in the parameters?
>> Perfect. So into our local memory first goes what parameter first?
>> The parameter label name?
>> Name. And it gets assigned what?
>> Value of Will?
>> Will. That's perfect and then score is 3. That means everywhere inside a user creator, now name will be Will and score will be 3 wherever you reference it.
[00:04:30] Sheldon, what's the next line of code? What's the left-hand side of the next line of code tell us to do Sheldon? Declare a new variable of new user.
>> Yeah, a new user, exactly.
>> As a user function store object.
>> Hmm, that seems reasonable. What do we say?
[00:04:53] Whatever we parse into object.create, what would it create? Griffin?
>> That would be a, it would create. A empty.
>> Empty object. Whatever I parse into object.create this line here saying, object.create. And then parsing in userFunctionStore. This user, all this does All this function does is, create an empty object.
[00:05:25] We are going to see what this special user function store thing does in a second. For now, all it does is creates an empty user, empty object, we are going to call new user. Sorry, not a new user object. An empty object. That we're gonna label newUser, that's all it does.
[00:05:47] That's all it does. It does something else as well. Because when would be a smart time for us to make the bond To this store of functions. Remember, our ultimate goal is we're gonna do this. Write, user1.increment. And even if we don't find, on user1, an increment function, still be somehow able to go and look In user function store, find increment, and run that functionality.
[00:06:21] Andrew, what would be a good time to make a special bond in this user one object to this shared user function store. When would be a good time to do that, do you think?
>> When you intialized it.
>> When we initially defined that object. Before we return, remember this object Is going to be returned out and stored in what variable?
[00:06:41] Griffin?
>> It would be stored in the user one?
>> User one, exactly. That's where it's gonna be stored. So this object we're giving birth to in here called new user, is going to end up being called user one. We're gonna end up [INAUDIBLE] increment on it But it's not gonna have hopefully directly on it any increment function.
[00:07:03] Do we see if we add one, or we're not gonna add one? But we know that we want to be able to still run increment. So somehow, when we hit user one to increment, we wanna be able to look at user one not find increment, and somehow look up this userfunction store and find an increment Meaning we've got to somehow make a bond between user one, that is new user, and somehow this user function store.
[00:07:27] Well it turns out that bond is made using this object.create, object creation format. We're gonna talk about where this special bond is hidden in a moment. For now, Just know that when I use object.create, I'm creating the object. But I do something else. Whatever I pass in to my parameters on object.create I'm gonna have on that empty object somehow a special bond to the thing I passed in that used the function store.
[00:08:01] Okay, we don't know how that happens yet, we just know somehow it's gonna happen in that user object. So let's now keep going. We've now finished the line, we use object.create. The new user became an object. This became an object but somehow this special bond. To user function store.
[00:08:21] This is the same object. We just wrote it on both sides. Somehow I got a special bond to user function store. All right, Katie, keep me going. Now we've finished with the line that created the object and made this special bond to user function store. What's our next line Katie?
[00:08:37]
>> We are going to assign The name input Will to newusers property name.
>> Very nice, yes.
>> And then create a new property score and assign 3.
>> Which is the score parameter, or argument. Yes, there it is. And now what're we gonna do, Katie?
>> We're gonna return that object.
[00:08:57]
>> Return that object out.
>> Just sign it.
>> And what's in that object? Nothing but name Will, score 3. Name Will, score 3. There's the object, and still Because we don't lose bonds after we make them. We never lose bonds after we make them still. That we return down that object.
[00:09:27] Stored it in user one. There's the object. There's the object. There's the object. We don't return bonds after we make them so it's still got it's still hidden somehow bond Up to user function store. Okay, we're gonna talk in a moment how has this been possible, how is this done?
[00:09:49] But for now, let's try and run, well, actually it's very important that I think, we do one more. Of these. Nah, it's fine. Let's try and run user1.increment, our fundamental goal. Can I be clear, does user 1 have an increment method on it? It doesn't. It's not on there, so this should fail, in theory.
[00:10:13] Of course it doesn't because we've done something really cool. So we're just going to skip for now, creating a brand. If we brand the next line, User two is the call to user creator with user five. We do a brand new excursion context inside of which we create a brand new object which itself would have a bond of user function store and would not have an increment method on it.
[00:10:34] We return that object out and return it to method two. Okay. We're gonna skip that line for now, and we're gonna encounter our all important line that is a measure of are we doing good work here. Can we do this, all right. Big moment. Can we do this?
[00:10:52] What do I do first Lindsey? I look for.
>> user1 object.
>> And what do I find? Time it.
>> Yes, and then I look for increment.
>> The method increment?
>> Yeah, do I find it on the object?
>> No.
>> No, do I panic?
>> No.
[00:11:09]
>> No, I don't panic. Where do I look, Lenzy next.
>> The special bond.
>> All the special bond where I find Use the function store and what property do I final it,
>> Increment.
>> Increment and it's got some functionality to run, so I create an execution context to run that functionality, there it is, I create an execution context to run that functionality, all right.
[00:11:37] I add user1.increment to my call stack, okay
>> Here we go. I'm calling user1.increment. What's the code say for the increment function, Lindsay? Do you see what the body of the code says?
>> Yes, it says this.score ++. Okay. So now we're going to be introduced to a special key word in JavaScript and in all [INAUDIBLE] languages in general [COUGH].
[00:12:07] This increment function, is it only going to be used by the User 1 object? It could be used by all of the objects we return, user 500, user 1000. So how are we gonna make sure when we run it that we're referring to the right object? Cuz we could call it in a moment on instead use a 5001.increment and I want to make sure that the functionality refers to the use of 5001.
[00:12:35] I can't right use the one, user 5001 inside of increments
>> Like I used to. So, what does JavaScript help me out by doing?
>> This.
>> The keyword of this. And the keyword this is like a placeholder. And actually, whenever I create an execution context, we don't usually say this.
[00:12:53] I fill in my arguments here, right? I fill in any variables and functions I annoumce, and JavaScript always but most of the time it's not that interesting for us, always also assign the value of this. And our basic fundamental rule is that this will refer inside its execution context to whatever Is the left of the dot where that function is being called upon.
[00:13:21] So what is to the left of the dot here, Ketty?
>> User1.
>> So what's gonna be filled in this. >. The user1.
>> Exactly. And so we will actually see here, this would have essentially become user1.score++. Now, where would we look for user1 first? [INAUDIBLE]
>> Yeah, it's not there, right?
[00:13:39] There's only this, it's empty. So where do we look next?
>> Global.
>> Do we panic and not find it? No, it's there. We find the score, what do we do with it?
>> Connect it.
>> Shit, we've achieved that goal. Although increment was not on the user one object.
[00:13:53] We've achieved our goal of running user one dot increment. Our functionality being available right there on our object that has the data we need. I can now pass it to user 1 anywhere I want. No problem, because look. Even though it's not on user 1, increment was somehow available.
[00:14:10] All right, let's talk about how it was available. Let's talk about how it was available. Well, it turns out. When I use object create and use a function store, yes I create an empty object. Yes it's an empty object, it was empty right until we filled in the properties.
[00:14:25] That leaves me with an empty object, but actually it does one thing behind the scenes. JavaScript needs a way of knowing where to go look for this user function store. It has a special hidden property. Now, it's not as hidden as square bracket, square bracket, scope, square bracket, you remember that one?
[00:14:43] Which you just can't access. This is one you could actually access. You can look in Chrome Dev Tools and press a down arrow and see it there. But it has a hidden property, which is this guy, __proto__ That is going to have, in here, a reference to, not a copy obviously, but a reference to user function store.
[00:15:03] It's actually through this, when I create new user, using object dot create, and pass user function sort, yes, I get empty object. This bit's hidden. If I were to console log new user At this point I will see an empty object, definitely, but if I were to then click, the little down arrow, I'd see, anyone ever clicked that down arrow on the Chrome Dev Tools where you get to see these random properties?
[00:15:30] Well one of them, _proto_ we can call it _proto_ like double underscore That sounded ridiculous. School, it's linking to whatever was parsed when we created this object through the object.create. What was parsed? User function store. So we get a link, and so when I return out the object, this object, this guy here.
[00:15:52] When I return it out and store it in user one Yes, it's user one. Just had this two properties but it also has a special bond through underscore proto underscore that is a reference to user function store. There it is, a reference to user function store Where, what do you know, there's the increment method on it.
[00:16:22] This reference, this bond is known as a prototype chain bond. We are setting and I hate this phrase I hate the way we phrase this, it's not helpful to me. But because it's actually scored, an underscore, proto-underscore. And often, people still say, you've seen a property-dot-prototype, this is not the same thing.
[00:16:45] We're doing to see what that is in a moment, that's coming in a second. But people often say, user1's prototype is user function store. I don't love that way of describing it But certainly user ones, technically this is prototype. But we access it or it's stored, it's referenced under this _proto, if you've ever seen a .prototype property that's not this.
[00:17:06] We're gonna see that in a second. It's referenced _proto_ is the bond to use the function store. So Griffin When I ran user1.increment, and I went and signed the line of code I thought was this.school.++. There it is. This was the user 1 right? So I'm actually doing user1.school.
[00:17:26] When I ran user1.increment, where did I look. Forgot what I was gonna say. W,hen I ran user1.increment, what did I look for first? You looked for user one.
>> User one, exactly. I went off to my global memory, did I find it?
>> Yes.
>> And then it says dot increment.
[00:17:43] Did I find dot increment on my object?
>> Nope.
>> No, so what did job descript interpret do with this runtime moment?
>> Check to see if you had a proto.
>> Check in the underscore proto underscore, and what did it find? A reference to a whole object and it when into that object and what did it find.
[00:18:02]
>> Increment.
>> Exactly, and that functionality used it to create excusion context, no problem. Okay lets have sums on this, this is the prototypal nature of javascript. Now if were done just being clear using 5001 dot increment. Suppose we had user 5001 will that have an increment method on it?
[00:18:22] No, but JavaScript knows to check the _proto_ in order to find a reference user function store, uses the same function. Now of course that means that this function better be generic, better be a general to be used on any object, use any user object Because otherwise we can't write like User5001.score.
[00:18:41] So instead we use this, which when the increment function ends up being called on the user one object, on the user 5001 object that this gets automatically filled in with whatever object is to the left of the dot. Which turns out, in this case, to be user1. And now this.score++ becomes user1.score++.