In JavaScript, the this keyword is very flexible and confusing, evaluated at runtime, can have different values depending in which context it appears, including but not limited to: function, class, global, and strict mode.
A common mistake for new JavaScript developers is to extract a method from an object, then later call that function and expect it to use the original object as its this, like using the method in callback-based code.
Here are common contexts in which this behaves differently:
this follows the rule of “global object in non-strict, undefined in strict”.function foo() {
console.log(this);
}
foo(); // "window" in browsers, "global" in Node.jsIn “strict mode”, the value of this is always undefined.
'use strict';
function foo() {
console.log(this);
}
foo(); // undefinedthis refers to the object before dot, the one used to call the method.const person = {
name: 'John',
greet() {
console.log(`Hello, my name is ${this.name}`);
}
};
person.greet(); // Output: Hello, my name is Johnthis refers to the HTML element that the event occurred on.const button = document.querySelector('button');
button.addEventListener('click', function() {
console.log(this === button); // Output: true
});this refers to the newly created object.function Person(name) {
this.name = name;
}
const john = new Person('John');
console.log(john.name); // Output: Johnbind(): This method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.const person = {
name: 'John',
greet() {
console.log(`Hello, my name is ${this.name}`);
}
};
const greet = person.greet.bind({ name: 'Jane' });
greet(); // Output: Hello, my name is Janecall() : This method calls the function with a given this value and arguments provided individually.const person = {
name: 'John',
greet() {
console.log(`Hello, my name is ${this.name}`);
}
};
person.greet.call({ name: 'Jane' }); // Output: Hello, my name is Janeapply(): This method calls the specified function with a given this value, and arguments provided as an array or an array-like object.const person = {
name: 'John',
greet(city) {
console.log(`Hello, my name is ${this.name} and I live in ${city}`);
}
};
person.greet.apply({ name: 'Jane' }, ['New York']); // Output: Hello, my name is Jane and I live in New Yorkthis value, but inherit it from the enclosing lexical context.const person = {
name: 'John',
greet: () => {
console.log(`Hello, my name is ${this.name}`);
}
};
person.greet(); // Output: Hello, my name is undefined