this in Method Calls

Marius Schulz
InstructorMarius Schulz
Share this video with your friends

Social Share Links

Send Tweet
Published 7 years ago
Updated 5 years ago

When a function is called as a method of an object, that function's this argument is set to the object the method is called on. That object is called the receiver of the function call.

Oftentimes, the receiver gets lost when we invoke a method as a function. This happens particularly often when passing a method as a callback to another function.

In this lesson we'll see how the receiver mechanism works, what problems it creates, and how to work around these problems using wrapper functions or the bind method.

Instructor: [00:00] When a function is called as a method of an object, that function's this argument is set to the object the method is called on. Here, we're calling person.sayHi, and therefore the this value within the sayHi method refers to person.

[00:20] We say that person is the receiver of the method call. This receiver mechanism is not affected by where the function was defined. For example, we could have defined the function separately, and could have later attached it to person. We're still writing person.sayHi, and therefore person will still be the receiver of the method call.

[00:48] Sometimes, the call site is a property chain which looks like this. In that case, the receiver is the most immediate property before the method, which is person in this example. The foo.bar prefix in the beginning doesn't influence our this binding.

[01:09] One of the most common frustrations that developers have with this is when a method loses its receiver. Consider our initial example again. If we store a reference to the sayHi method in a variable, and later call that variable as a function, our intended receiver is lost. Within the sayHi function, this will refer to the global object, and not to person.

[01:37] This is because we now have a plain function call, and we're not in strict mode. Losing a receiver this way usually happens when we pass a method as a callback to another function. For example, setTimeout.

[01:50] setTimeout will call our function with this set to the global object, which is probably not what we intended here. One solution to this problem is to add a wrapper function. That way, person.sayHi is still invoked as a method, and doesn't lose its intended receiver.

[02:16] Another solution that I want to mention here for the sake of completeness is the bind method, which allows us to tie our this to a specific object. We're going to talk about the bind method in detail in a future lesson.

David Chan
David Chan
~ 6 years ago

There are many typos in this code snippet.

Marius Schulz
Marius Schulzinstructor
~ 6 years ago

There are many typos in this code snippet.

Could you please point out the typos? I can’t seem to find a single one. 🤔

David Chan
David Chan
~ 6 years ago

There are many typos in this code snippet.

Could you please point out the typos? I can’t seem to find a single one. 🤔

Sorry, I might not point it out clearly, it's actually the code snippet in the Transcript part.

Typos are like

const person = {
    console.log(`Hi, my name is ${this.firstName}!`);
};

sayHi() {
    firstName: "John",
}

and

const greet = person.sayHi();
greet();
Pesto
Pesto
~ 6 years ago

why does wrapping the call to sayHi inside setTimeout() with a function

fn(){
person.sayHi();
} 

didn't set 'this' to global? I get why it is happening without the fn() but not this part.

Marius Schulz
Marius Schulzinstructor
~ 6 years ago

@Pesto: Within the wrapper function, person.sayHi() invokes the sayHi with person as a receiver. sayHi is invoked as a method, and it doesn't matter what value this has within the surrounding scope.

Lars Devocht
Lars Devocht
~ 5 years ago

@Maris: Especially useful are your hints to solve the issue of losing the receiver of a method call. Some teachers present it as a language error and then solve it with a fallback to lexical scoping with self=this. The best explanation about "this" I found so far. Thank you.

Markdown supported.
Become a member to join the discussionEnroll Today