key points:
this refers to the current context in which the code is executing. The value of this is determined dynamically based on how and where the function is called:
- In the global scope,
thisrefers to the global object. - In regular functions,
thisdepends on how the function is invoked (object method, global function call, etc.). - In arrow functions,
thisis inherited from the parent function (or the surrounding scope) and does not change based on how the function is called.
Arrow Function
define
- Arrow functions inherit
thisfrom the enclosing lexical scope, which means they takethisfrom the nearest regular function that encloses them, not from block constructs likeif,for, orwhileblocks. - In other word,
thisrefers to the context of the parent function (or the surrounding scope) where the arrow function is defined.
the nearest regular function
const person = {
name: 'Alice',
greet: function() {
const arrowFunc = () => {
console.log(this.name); // `this` refers to `person`
};
arrowFunc();
}
};
person.greet(); // Output: "Alice"
Steps:
- The arrow function inside
greetinheritsthisfrom its lexical scope. - The nearest regular function is
greet. - When
greetis called asperson.greet(), thethisingreetrefers to thepersonobject because it's called as a method onperson. - Therefore, the arrow function inside
greetinheritsthisfromgreet, which refers toperson.
const person = {
name: 'Bob',
greet: function() {
if (true) {
const arrowFunc = () => {
console.log(this.name); // `this` still refers to `person`
};
arrowFunc();
}
}
};
person.greet(); // Output: "Bob"
Standalone Function Called
this refers to window object
var length 4;
function callback(){
console.log(this.length);//What is logged?
}
const object = {
length:5,
method(fn){
fn();
};
}
object.method(callback);//4
// actually it is a independent call
Object Method Called
this refers to the object calls method
const objA = {
type: "A",
foo() {
console.log(this.type)
}
}
const objB = {
type: "B",
foo: objA.foo,
bar: () => objA.foo(),
baz() { objA.foo() }
}
objB.foo();
objB.bar();
objB.baz();
Passing a function as an argument or callback fuction
When dealing with regular functions passed as arguments or used as callbacks, the behavior of this depends on how those functions are invoked.
Regular Function as Callback
- example 1
const obj = {
name: 'Alice',
greet: function() {
setInterval(function() {
console.log(this.name); // `this` is `undefined` or `window`, not `obj`
}, 1000);
}
};
obj.greet(); // Output: `undefined` (or nothing in strict mode)
The setInterval function receive a callback function. The callback function excute by Function call, so this refers to the global object.
- example 2
const user = {
name:"Piyush Agarwal!",
logMessage(){
console.log(this);//What is logged?
},
}
setTimeout(user.logMessage,1000); //window
Steps:
- By writing
user.logMessage, you're referring to the method, but you're not actually calling it. You're simply passing a reference to the function. - When called normally (like
user.logMessage()),thiswould refer to theuserobject. - When you pass
user.logMessageas a callback tosetTimeout, it loses its original context (user). - This means that when
setTimeoutinvokeslogMessage, it's not called as a method ofuser, but as a regular function call.
Arrow Function as Callback
- example 1
const obj = {
name: 'Bob',
greet: function() {
setInterval(() => {
console.log(this.name); // `this` refers to `obj`
}, 1000);
}
};
obj.greet(); // Output: "Bob" every second
The callback function is arrow function. The arrow fucntions do have this, it inherit from parent function(greet). The greet function was method called, so this refers to the obj object.
- example 2
const user = {
name:"Piyush Agarwal!",
logMessage(){
console.log(this);//What is logged?
},
}
setTimeout(()=>user.logMessage(),1000); //window
In this case, logMessage was called by user. This refers to the user object.