Understanding `this` in JavaScript
JavaScript’s this keyword is notorious for confusing beginners.
Unlike many programming languages, the value of this in JavaScript is not always obvious and can change depending on how a function is called.
This guide will break down how this works in different contexts to help JavaScript beginners master this essential concept.
What is this?
In JavaScript, this is a special keyword that refers to the object that is currently executing the code.
Think of it as a reference that automatically gets created when a function runs, pointing to the “owner” of that function.
The Five Rules of this
Let’s examine the five primary contexts that determine what this refers to:
1. Global Context
When used outside of any function or object, this refers to the global object:
- In browsers:
thisequalswindow - In Node.js:
thisequalsglobal
1 | |
2. Object Method Context
When a function is called as a method of an object, this refers to the object that owns the method:
1 | |
Here, this inside the greet method refers to the person object.
3. Function Context
When a function is called on its own (not as a method of an object), this defaults to the global object in non-strict mode:
1 | |
In strict mode, this becomes undefined:
1 | |
4. Constructor Context
When a function is used as a constructor with the new keyword, this refers to the newly created instance:
1 | |
5. Event Handler Context
In event handlers, this typically refers to the element that received the event:
1 | |
Changing this with call(), apply(), and bind()
JavaScript provides three methods to control what this refers to:
call()
call() allows you to call a function with a specified this value and arguments:
1 | |
apply()
apply() is similar to call(), but it accepts arguments as an array:
1 | |
bind()
bind() creates a new function with a fixed this value:
1 | |
Arrow Functions and this
Arrow functions don’t have their own this binding. Instead, they inherit this from the surrounding code:
1 | |
In this example, the arrow function in greetArrow inherits this from its surrounding context (the person object), while the regular function in greetRegular has its own this context.
Common Pitfalls and Solutions
Losing this Context
A common issue is losing the this context when passing methods as callbacks:
1 | |
Solutions:
Use
bind():1
setTimeout(person.greet.bind(person), 100);Use an arrow function:
1
setTimeout(() => person.greet(), 100);
this in Nested Functions
Inside nested functions, this doesn’t refer to the outer function’s this:
1 | |
Solutions:
Store
thisin a variable:1
2
3
4
5
6
7
8
9
10const person = {
name: "John",
greet: function() {
const self = this;
function getGreeting() {
return "Hello, my name is " + self.name;
}
console.log(getGreeting());
}
};Use an arrow function:
1
2
3
4
5
6
7
8
9const person = {
name: "John",
greet: function() {
const getGreeting = () => {
return "Hello, my name is " + this.name;
};
console.log(getGreeting());
}
};
Conclusion
Understanding this in JavaScript is crucial for effective programming.
Remember these key points:
- The value of
thisdepends on how a function is called, not where it’s defined - Methods like
call(),apply(), andbind()let you control whatthisrefers to - Arrow functions inherit
thisfrom their surrounding context - In most cases where
thisbehavior seems confusing, arrow functions can be a simple solution
By mastering these concepts, you’ll have a much easier time working with JavaScript objects and functions, and you’ll write more elegant and bug-free code.