JavaScript: The Hard Parts, v3

Prototypes & Object.create()

Will Sentance
Codesmith
JavaScript: The Hard Parts, v3

Lesson Description

The "Prototypes & Object.create()" Lesson is part of the full, JavaScript: The Hard Parts, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Will explains how to create objects using the Object.create() method to link new objects to a shared function store via the prototype chain. This approach allows multiple user objects to share one copy of functions like increment without duplicating them on each object.

Preview

Transcript from the "Prototypes & Object.create()" Lesson

[00:00:00]
>> Will Sentance: So now people, we are going to create our objects using the Object.create approach and taking advantage of this chain, known as the prototype chain that's going to allow us to have objects that do not have a function on them, to nevertheless know somewhere to go and look to find that function automatically. Doing so will enable us to get all the benefits from our only goal that I can run user1 and user2.increment, so that I can run my functionality on the pertinent data, not randomly off in my code, but on the pertinent data of the user.

[00:00:35]
But I don't want to have to have a copy of that increment function on user1, and user2, and user400, and user700. Instead, I want to have one copy of the increment function, but not have to go and manually access it, but instead still run increment and know that JavaScript can go and find that single copy. And that is going to enable this approach to be essentially pretty functional. We're going to end up refining this with a lot of shorthands, or not a lot of shorthands, one particular shorthand, a three letter word, that's going to enable a lot of the stuff we do in here to be done automatically for us.

[00:01:16]
What do you think that three letter word might be? Well done, yeah, people, we'll see it. OK. But for now, solution two, into JavaScript land we go, let's have a memory. There it is. There's my straight line, relatively so, and into it we go. Let's get bouncing through this code. Chris, kick me off, what are we declaring? User creator. User creator, which is a function definition, just like any other.

[00:01:49]
Next line, Chris, what are we declaring there? User function stored. Yeah, and what is it? That is an object. It's an object, yeah, don't get tricked people by its look, and it's got functions stored on it, but it is an object. And what are the methods stored on it? Increment, increment, which is a function, which is a function, and login. Log in, which is another function. Beautiful, thank you to Chris.

[00:02:15]
Now we hear Chris declaring what on the left-hand side? Oh, user1. User1, do we know what to store in it yet? No, we've got to go and do what? User creator. And pass in what arguments? Ari and 3. Ari and 3, and we're going to create everybody a brand new what? Execution. Well done everyone, yay, you're all my besties, and into it we go, and in our local memory, we are going to. Oh, I hope there's enough room.

[00:02:54]
It's enough room, OK. And into it we're going to go. And be really clear people here, we're going to deal just with the arguments and parameters, we are not doing anything with any objects or anything, we're just dealing with good old regular arguments, filling in our parameters. What are our two parameter names? Matt, what are our two parameters here? Name and score. Name and score, and we're going to assign to them the arguments that got passed in, which are what?

[00:03:23]
Ari and 3, yep, hold on. Now, people. Does this look a bit like an object? It's sort of, right, because it's definitely not, it's just the stored data just like anything else in memory in our local execution context. Do not think that this is an object in some way, just a gotcha that people fall into. What are we declaring next, Tenzin, inside our user creator call with the input of Ari and 3? We've assigned our arguments to our parameters.

[00:03:46]
You know, as people often say, we've done our argument parameter assignment, we've got that bit out of the way, and now we hit the body of the user creator function where we declare what? Declared the const new user object. Yes, we declared new user and assign it a, well, OK, you tricked me. We've got to do some work. It's interesting you say we create, we assign the new user object, let's be really precise.

[00:04:22]
We create a label new user. What's going to be assigned to new user, as a result of the call to the built-in function Object.create that we are passing? The argument, thank you, yes, a blank, an empty object, I like a blank object, exactly, an empty object. Do not get it twisted, that is a big old empty object. OK Now, do I say right now that it's going to get, hm, hm. It's an empty object. OK, let's assign some properties to it.

[00:05:03]
Do I say right now that it's going to have, oh, whatever. I can't decide what I'm going to say right now, but we know, don't we, right, that this big old empty object is somehow, as yet unknown, going to get a bond to what? To user function store, we don't know how, but we know it's going to get a bond there somehow. Exactly, but for now, we plow on, because it's a big old empty object, I cannot stress, I mean, you can probably imagine it's going to have some sort of hidden property, but it's a big old empty object into which, Joe, we're going to assign what first property name?

[00:05:43]
I will assign a new property name of name. Yes, very unhelpful, isn't it? Yes, name to which we are going to then store what value? The value of the argument passed for name, which in this case is Ari. OK, can we just give a little hand there to Joe, because that precision is really important. Everyone on the stream is going, ah, got it, now I know exactly what's happening. Well done. And the next one, Joe, do you have to do it all again now, don't get it wrong.

[00:06:08]
Create a new property called score, and we assign to it the value of the argument passed for the parameter score in this instance, score equals 3. Oh, he's too good, OK, let's give him a hand again. Oh, very good, Joe, well done. And now we hit return, so I wasn't actually upset that you did so well, I'm really happy. Return new user, which we heard Tenzin earlier say is going to return this object, this whole object here, out into our global label, user1.

[00:06:55]
There it is, and it's got name of Ari and score of 3, and somehow, it's got a hidden link up to this user function store. But for now, this execution context is closed, yep, popped off the call stack. And we hit our next execution of user creator, whose output is going to go into user2, and it's going to create a new execution context for running user creator again, this time with J and the input of 5.

[00:07:31]
Brand new execution context, we're going to run a brand new running of Object.create, which is going to return a brand new object, it's going to store a brand new object inside new user. Do we need to show this again? Yes, we do, we can always skip it up, we can always skip it in post. There we go, we'll keep it small. There it is. Inside we dig, oh, we first do our local memory. Where we are going to assign our name parameter to the argument of J, our score parameter to the argument of 5, create a new constant, a new user, what do we store in it, we don't know yet, but we're going to call Object.create, which we're then going to pass in user function store, UFS, I'm just going to refer to it here.

[00:08:25]
And that's going to return out a big old empty object. Into that object, we're going to then create a name property to which we're going to assign, I'm going to try and do as well as Joe here, to which we're going to assign the value of our name parameter, which at this point is the string J, the argument passed in, and the value of our score parameter to a brand new score property name, which at this point is the value of 5, the argument that was passed in.

[00:09:04]
Not quite as crisp as Joe, but in the right direction. And it also will have on it because it was created with this somehow hidden link to user function store, a link up to our user function store. We then return this object out into user2, and there it is with name, J score, 5, and somehow this link up to user function store. Yeah, go ahead, Joe. I have, I think maybe two clarifying questions that might have more to do with the instantiation of the object.

[00:09:43]
One is, when we're returning these objects to their user1 and user2, are they also carrying with them the enclosure that contains the parameter that was used and the new user keyed to the shape of the object? Or are we discarding those because we're using the Object.create function? We're not discarding because of that. Do we have a function assigned on here? No. No, and so do we have access to the surrounding data after correct, right, so it's the function, it's the presence of the function that keeps the enclosure with it.

[00:10:27]
Thank you. Exactly. OK, so I had one other, yeah, go ahead, is there any key distinction, say, in the user creator function, if we were to just inline return Object.create user function and say that, is there anything we lose or gain when we're actually calling a new user in that local memory for me? My only problem with that is if we returned Object.create user function store straight there, how would we add properties to it?

[00:10:48]
Yeah, we wouldn't get to add any properties to it, yeah, yeah. And that's also really illuminating, right, because you might think, but surely I passed them in, aren't they attached? Uh uh. Passing them in as arguments, as you put it so well, just put them in our local memory. We had to manually put them on the object we created. Great stuff, Joe. All right, all to say execution context's gone, execution context's gone, and we now hit our important check.

[00:11:23]
User1.increment. All I want to be able to do, people, I have only one goal in life, love, and yeah, only one goal, and that is that I can run this damn increment function on the data in user1, not have to go hunt for it off somewhere else and call it, and then pass user1 in, but I can just go user1 and run the functionality on the user1. Let's do some lookup. Chris, you're in charge of look-ups for now.

[00:11:54]
User1, where's JavaScript go looking for it? Global memory. Does it find it? Yes. You bet it does. Increment method, is it name? No. Is it score? No. Uh oh. Does JavaScript panic? No. Yeah, it panics exactly, yes it does, no it doesn't because, and I don't know if I should have left this for a big reveal here, but we saw what did our user1 and user2 each respectively get when they were created inside of the user creator function using the Object.create way of creating an empty object to which we assigned the arguments as properties manually.

[00:12:38]
They didn't just actually get an empty object. In user1 now, and user2 now, respectively, there is also a hidden property, a hidden link up to user function store. Can anyone guess? Well, it used to be called something else. Now, in the spec, it is more, even perhaps more confusingly, well, I don't know. What is the name of that hidden property? Can anyone guess what the name of that hidden property might be?

[00:13:00]
Yes, prototype. Exactly, in our little square brackets, meaning we can't get access to it, but JavaScript knows it's there, is square bracket, square bracket, prototype, square bracket, square bracket. If you console log user1, I mean, actually, to be fair, in the console, you can press a little down arrow and see that. The console helps to, is there to try and help you. But if you were to loop through the properties, you ain't seen that one.

[00:13:34]
That one ain't visible. But it is a reference, a link up to our user function store, and the same thing on our user2, a hidden property, square bracket, square bracket, prototype, square bracket, square bracket, it was set at the moment that this object was created and stored in a new user, with the user function store passed into the Object.create, it set that square bracket, prototype, square bracket, link to user function store, that square bracket, prototype, square bracket, link to user function store.

[00:14:15]
So Chris, when JavaScript fails to find a name or score, the only two properties in that list of properties here, it fails to find increment, it doesn't panic, where does it go, and automatically make sure to check first. Chris. Prototype, prototype, and it finds a link up to user function store where, what does it retrieve, Chris? Increment, increment, and so it can run it and create a new execution context to run increment.

[00:14:41]
Let's look at that increment function into this execution context, we go. We have a problem, people. This increment function is going to be used, one saved version of it. I don't even like using the word copy because it's not a copy of somewhere else, one saved version of it. One instance is a term people use, but again, these have very big connotations in other languages of what an instance is coming from.

[00:15:19]
So I'm just going to say one saved version of the increment function in memory is going to need to be used for user1, and user2, and user400, and user700, and user1020. Before we referred to it, well, actually in the very first example, as user1.score, what was it, user1.score plus plus, and then we could increment score 3 to 4, user2.score plus plus 5 to 6. But we now need to ensure that this increment function works on user1, and user2, and user5, and user100.

[00:15:51]
We need to somehow know how to refer to the object that the function increment has been called on, it doesn't know which one it's going to get called on. It needs something in local memory that will automatically be assigned to the object on which it's running. What built in, we call it implicit parameter. It's a parameter that shows up here without us having to do the defining of our or the specifying of ourselves.

[00:16:25]
What implicit parameter shows up immediately in this local memory? Anyone know? Yeah, go ahead, Michael. This immediately in our local memory, we get the implicit parameter this, which is going to point to always, whatever, always, we'll see later on, but always, whatever object is to the left-hand side of the dot that that increment function is being run on. So in this case, the this would resolve to what Matt?

[00:16:58]
It would resolve to the user. To which, to which user? User1, spot on. If we ran increment, if we went user2.increment, go and grab the increment function, brand new execution context, that this would become what Matt? User2. And so we've made sure to write our code, I hope, to refer to that this implicit parameter, did we? OK, we did, this.score plus plus. So out of this, it will evaluate to user1.score plus plus.

[00:17:25]
Now it's a little bit kind of funny, even though the this is referring to user1, the user1 here is going to look in local memory. Does it find, sorry, the increment method is going to look in local memory for user1, does it find it there? No, but that's not a bad thing, we find it off in global, where we find user1, and we look for what property on it, Matt? Score, score and we do what to it? Add one, increment it to 4, beautiful from Matt, exactly right people.

[00:17:55]
We've had to introduce, in order that this function can be used on all and any object on which it's called, automatically accessible because of our hidden prototype reference up to this user function store, that increment method. It needs to work on user1, user2, user500. So how the heck does it know when it runs which object it's running on? Don't panic, it automatically fills into local memory, this, and fills in with it a reference, a link to whatever the object is that it's being run on, so that we can make sure we wrote our code appropriately by referencing that this, and then that will evaluate to, that will turn into whatever the this is for that running, which is user1.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now