Check out a free preview of the full The Hard Parts of Object Oriented JavaScript course

The "Calling Prototype Methods" Lesson is part of the full, The Hard Parts of Object Oriented JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

Will refactors solution 3 to include the implicit parameter, this. As the solution is diagramed, attention is given to when this is useful, and how scope comes into play.


Transcript from the "Calling Prototype Methods" Lesson

>> Will Sentance: Let's just walk through this code here and it's a walkthrough our call of the increment method. Let's see it actually play out. So we are calling user1.increment. Elliot taught me through the look up process of this increment function, and let's see what actually happens. Taught me through the look up process, Elliot.

>> Elliot: We look in global memory for User 1.
>> Will Sentance: Find it.
>> Elliot: Find it and then we look for increment.
>> Will Sentance: Do we find it?
>> Elliot: No, we don't find it.
>> Will Sentance: We do not. Do we panic?
>> Elliot: Nope.
>> Will Sentance: We do not. JavaScript looks on the?
>> Elliot: Proto.

>> Will Sentance: And it finds a link up to?
>> Elliot: The prototype object.
>> Will Sentance: Object on the user creator object, yep, and then we find?
>> Elliot: Increment.
>> Will Sentance: Increment. Let's not just say, success, we found the function we can call it, let's actually now execute that code and let’s see what happens.

Recording the function increment, let's create everybody a new?
>> Elliot: Memory.
>> Will Sentance: [LAUGH] That's part of it. A new?
>> Will Sentance: Let's create an execution context, there it is. What's the line of code inside of it? Seth, what is the line of code, just literally give me the line of code.

>> Seth: this.score-
>> Will Sentance: this.score-
>> Seth: ++
>> Will Sentance: ++, fantastic. Folk, they've got a portion name for this, it's called an implicit parameter. I learned that name recently. Look, this increment function now, we don't have a unique copy of it designed just for User 1. Nor do we have a unique copy of it designed just for User 2.

Let's actually just quickly create a User 2 so we can really, explicitly see this. There's a user 2 with, I don't know, let's say name, Jeff, a score of 8. And it too has a protobond up to.
>> Will Sentance: So both User 2 and what it says, it's User 20, actually.

Both User 20 and User 1 are gonna be using this same increment function. So how are we gonna make sure that it explicitly targets User 1? Cuz if I wrote the code in here instead to say user1.score++, such that I would go to User 1, increment its score.

Well now, I'm using that same function on User 20. All I ever gonna do is increase User 1's score. So I've got to make my function general, enough that it can work on any of these objects. Now normally, when I want to be general, I use a parameter such as when I call multiply by 2, it's not multiply 3 by 2 the function, it's multiply something by 2.

And when I call the function, I determine what that thing is, and I replace the placeholder, let's say, num with four or three, or whatever. Well, we got a problem here, that this function similarly needs to be, when it's called, applied to a particular object, the one that's pertinent to this moment.

What placeholder, they call it actually, I discovered, implicit parameter, it's implicit. It's one we don't explicitly state but it's put in there for us. What implicit parameter, what placeholder, this JavaScript give us, Terry, that allows us to refer to the pertinent object at hand?
>> Terry: This.
>> Will Sentance: This.

And it is a totally different, this, to the one we have when we created the objects. When the object was also created, it got the label, this, and then the object was returned out to use the one. And not, this, because its execution context was deleted, though this was definitely lost.

But the object was returned out. The, this, here is a totally different this. And there is one simple rule for its use. Whenever I call a method, a method is a function on an object, it always, when I call that clear the execution context, immediately, in the local memory, there is a this assignment.

In fact, there is a this assignment, a this declaration with a value, the whole time in JavaScript. Any execution context has a this. The global execution context has one. And the this there refers to that global window thing. Regular functions, not cool with new, or called on to the right-hand side of a dot.

They also have a this inside of it, but it's pretty useless. It always refer to that weird global object thing, it's pretty useless. But there is a profound use when I'm trying to call a function. When I'm trying to write a function, like increment, that will refer to the right object at the right moment.

And there is one simple rule, when I call a method, a function to the right-hand side of the dot, it will automatically, as soon as that function gets called, its execution context opens, the this will point to the object to the left-hand side of the dot. So Nick, what, when we call increment, will the this immediately be assigned to?

>> Will Sentance: What's to the left-hand side of the dot, Chris?
>> Chris: User 1.
>> Will Sentance: To User 1, to User 1. And so, David, when we run increment on User 1, there was no increment function on User 1 itself, it was in this set of shared functions. We want to make sure it can work on User 1 and User 20, well, we're running it on User 1.

What does the this.score++ evaluate to?
>> David: User 1's score.
>> Will Sentance: Fantastic. User1.score++, let's do our lookup journey. We look for User 1 in local memory, it ain't there, we look out to go up There it is, and we increment it. But what if it had been on User20.increment?

Let's do that journey, let's make sure we're really, really clear on this and it's a bit repetitive. But let's make sure we're really clear on this. Nick, User20.increment. We look up?
>> Nick: User20.increment will look to see if increment is in its object, and it's not.
>> Will Sentance: Fantastic.
>> Nick: It then doesn't give up, and goes to proto.

>> Will Sentance: Fantastic.
>> Nick: And then-
>> Will Sentance: We're going to go to proto, sorry, which takes us to userCreator prototype-
>> Nick: And it finds increment there.
>> Will Sentance: We grab its code.
>> Nick: We grab that.
>> Will Sentance: We create?
>> Nick: Execution context.
>> Will Sentance: Fantastic, and into it we go. What's the immediate thing that's assigned in local memory?

>> Nick: This.
>> Will Sentance: This, which is automatically assigned to whatever is to the left-hand side of the dot on which that execution call is being called. So Nick, what is a this?
>> Nick: This is User 20.
>> Will Sentance: User 20, fantastic, Matt. Well, look at that. This is very helpful.

Now, we've got a this.score++ that's gonna actually have a meaning. And so, I have this.score++ is going to evaluate to, Nick?
>> Nick: User20.score.
>> Will Sentance: Fantastic. We look for the User 20 locally, it's not there, we look to global, it's there and we increment it. Beautiful. Okay, this is a different use of the keyword, this, to that use of the keyword, this.

They are totally unrelated, totally unrelated. One is the auto-assignment of this, which, in other languages, that's not a crazy thing, because these things are closer. But in JavaScript, I really wish they'd called, I don't know, I really wish they'd given them different labels. One is, I call this one auto-create object.

>> Nick: This and that, so.
>> Will Sentance: Yeah, I just wish it said, so you could then go auto-create an equals name. How much more clear would that be, rather than this? What the hell does this mean? I always feel like language designers get really familiar with things that become almost intuitive to them.

And therefore, they design their new language as though this is a relevant, a sensible name for an auto-create object. No, no, call it auto-creator object, and call this one the object at hand, the objectathand.score++. My languages would be very verbose if I created a language. It would be a very long form language.

All right, so let's do this again. This time, the only thing that's changed is our increment function now has a little function declared inside of it, whether this.score++ is being stored, and then we're gonna run that. Now, in reality, we're never gonna store and add one function that does one line of code and then call it, we're just gonna do it directly.

But, I'm doing this cuz I wanna reveal something that is probably the biggest gotcha in object-oriented programming. This is the biggest gotcha in OOP, okay? And I was, I gave this talk a few days ago and I asked someone who had been interviewed recently, this question came up in their interview.

It is a favorite gotcha bug in OOP. So we're gonna understand how to solve it, and also why it happens.

Learn Straight from the Experts Who Shape the Modern Web

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