Problem Statement
Explain the this keyword in JavaScript. How does its value change in different contexts?
Explanation
The this keyword refers to the object that is executing the current function. Its value depends on how and where the function is called, not where it is defined.
In global context, this refers to the window object in browsers or global in Node JS.
In object methods, this refers to the object that owns the method. When you call object method, this inside the method is the object.
In regular functions called standalone, this is window in non-strict mode or undefined in strict mode.
In arrow functions, this is lexically inherited from the parent scope. Arrow functions do not have their own this binding.
In constructor functions with new, this refers to the newly created object.
In event handlers, this typically refers to the element that triggered the event.
You can explicitly set this using call, apply, or bind methods.
Common mistakes:
Losing this when passing methods as callbacks. Arrow functions in object methods not having access to the object. Not understanding that this is determined by call time, not definition time.
Understanding this is crucial for object-oriented programming and working with callbacks in JavaScript.
Code Solution
SolutionRead Only
// Global context
console.log(this); // window (browser) or global (Node)
// Object method
const person = {
name: 'John',
greet: function() {
console.log(this.name); // 'John' (this = person)
}
};
person.greet();
// Lost context
const greetFunc = person.greet;
greetFunc(); // undefined (this = window or undefined)
// Arrow function (lexical this)
const obj = {
name: 'Object',
regularFunc: function() {
console.log(this.name); // 'Object'
},
arrowFunc: () => {
console.log(this.name); // undefined (this from parent scope)
}
};
// Constructor function
function Person(name) {
this.name = name; // this = new empty object
}
const p = new Person('Jane');
console.log(p.name); // 'Jane'
// Explicit binding
function sayName() {
console.log(this.name);
}
const user = {name: 'Bob'};
sayName.call(user); // 'Bob' (this = user)
sayName.apply(user); // 'Bob' (this = user)
const bound = sayName.bind(user);
bound(); // 'Bob' (this permanently bound to user)
// Event handler
button.addEventListener('click', function() {
console.log(this); // button element
});
// Arrow function in method
const timer = {
seconds: 0,
start: function() {
setInterval(() => {
this.seconds++; // this = timer (inherited)
console.log(this.seconds);
}, 1000);
}
};