In this blog I will be going through this tricky JS interview question which lot of people find confusing initially.
Let's get started.
1. What will be the output of this?
function Person(name) {
this.name = name;
this.getName = function () {
console.log(`The name is ${this.name}`);
};
}
const getPersonObj = new Person('sam');
setTimeout(getPersonObj.getName, 1000);
The name is sam
After 1 sec, right? No ,Let's check its execution first.
1. A new object is created using Person object(functions are also object in JS)
2. then getName function is registered in web api to be executed after 1s
3. After 1 sec, getName method is pushed into callback queue and executed but this doesn't refer to our obj. why?
Because we are passing the reference of our object method as a standalone function inside settimeout
and for regular function context of this
is attached during the time it's called. In our case, It's equivalent to below function call and by default it will point to global object(window
in browsers).
const functionRef=getPersonObj.getName;
setTimeout(functionRef, 1000); // name is undefined in global context
How we can fix this?
- Context binding: we can bind the context of this before passing it as ref so that It retains the context throughout. you can read more about it here.
setTimeout(getPersonObj.getName.bind(getPersonObj), 1000);
Arrow function: Since arrow functions inherit the this context from its lexical scope and it will correctly point it to our object.
setTimeout(()=>getPersonObj.getName(), 1000);
Always remember, for regular functions, the context is defined when the function is called. The object on the left side of the function will always be the context (by default, it points to the global object). For arrow functions, the context is defined lexically. They inherit the value of this
from their lexical scope.
I hope It was helpful for you and would love to hear your suggestions.