In simple terms, this
is a special keyword in JavaScript that refers to the current object or execution context in which a function is being called.
In JavaScript, the behavior of this
is one of the concepts that is most difficult to understand because it is different from that in most languages.
The important thing is that this
always refers to the execution context of the function. This execution context can be:
- The global context when calling a function from outside an object
- The object that calls a method from within the object.
- A specific object that we “force” explicitly (using
call()
,apply()
, orbind()
methods).
Let’s look at each of them in detail 👇
Behavior of this in Different Contexts
In JavaScript, the value of this
depends on how the function is called, not how it is defined.
In Regular Functions
When a function is invoked simply (without using objects or special methods), this
refers to the global context.
function greet() {
console.log(this); // `this` refers to the global object
console.log("Hello!");
}
greet();
In this case, when greet()
is executed, the value of this
is the global object. (window
in a browser or global
in Node.js)
In strict mode ("use strict";
), this
does not refer to the global object, but will be undefined
.
From Object Methods
When a function is invoked as a method of an object, the value of this
refers to the object to which the method belongs.
const person = {
name: "Luis",
greet: function() {
console.log(this.name); // `this` refers to the `person` object
}
};
person.greet(); // Output: "Luis"
In this case, when person.greet()
is invoked, this
refers to the person
object, allowing access to the name
property within the method.
Loss of the this Object
One of the most troublesome things about this
is that it is easy to “lose” the reference to the object we wanted.
When we define a function inside a method, if we are not careful, this
could refer to the global object instead of the expected object.
const person = {
name: "Luis",
greet: function() {
function innerGreet() {
console.log(this.name); // `this` refers to the global object
}
innerGreet();
}
};
person.greet(); // Error: `this.name` is `undefined`, since `this` is the global object
In this example,
- Inside
greet()
, we define theinnerGreet()
function. - However,
this
ininnerGreet()
does not refer toperson
, but to the global context. - This can cause the
name
property to not be accessed correctly.
this in Arrow Functions
Arrow functions in JavaScript have a special behavior regarding this
.
Instead of setting their own value of this
, arrow functions inherit the value of this
from the lexical context in which they were defined.
const person = {
name: "Luis",
greet: function() {
const sayHello = () => {
console.log("Hello, I am " + this.name); // `this` refers to `person`
};
sayHello();
}
};
person.greet(); // "Hello, I am Luis"
In this case,
person
is an object with aname
property and agreet
method.- Inside the
greet
method, we define an arrow function calledsayHello
. - The arrow function inherits the context of
this
from thegreet
method, which points to theperson
object. - When calling
sayHello
, it uses the “correct” value ofthis
and accessesperson.name
.
Explicit Modification
In JavaScript, we can explicitly modify the value of this
using the call()
, apply()
, and bind()
methods.
These methods allow setting the execution context for a function, regardless of how it is invoked.
We see it in the entry How Call, Apply, and Bind Work in JavaScript
Summary of everything we’ve seen:
- In regular functions,
this
refers to the global context. - In object methods,
this
refers to the object that contains the method. - In functions within methods, we need to be careful, as
this
can change depending on the context of the inner function. - Arrow functions do not have their own
this
, but inheritthis
from their lexical context. - call(), apply(), and bind() allow us to explicitly change the value of
this
when invoking a function.