Understanding “This” in javascript through interview questions

It took me a good amount of time to understand how exactly “this” resolves in javascript. Even if i could get the answer right the explanation most of the time was not correct. After fishing through the sea of articles, blogs & documentations i consolidated a few examples which i will write here so that it will save your time tremendously in understanding the tricky questions related to “this”
Before we move on learn these facts :
- If an object obj calls any named or anonymous function myfunc then this inside this function would point to obj.
- If any named or anonymous function is called independently without any object attached with it, then this inside the function points to the global scope.
- For arrow function, the this points to the enclosing scope or the outer function. The focus is on scope only and not on the calling object i.e this is not bound to the calling object. Hence not suitable for object method when you want to access this.
Examples based on point 1
var solarSystem = { name : "Solar System", getName : function() { console.log(this.name) // Solar System }
}solarSystem.getName();
solarSystem is an object with name and getName properties. When i call getName() , solarSystem is the calling object. Which means inside getName() the this is equals to solarSystem object. Hence the output is Solar System.
Examples based on point 2
var solarSystem = { name : "Solar System", getName : function() { console.log(this.name) // Solar System. var getInnerName = function() { console.log(this.name) // undefined
} getInnerName() }
}solarSystem.getName();
Explanation:
getInnerName() is called without any calling object and hence called independently. As such the this inside getInnerName points to the global object. One can imagine this scenario as getInnerName() is replaced by window.getInnerName() at runtime. And now by rule 1 this inside the getInnerName() must point to window. Since we haven’t defined any name property globally. Hence the value is undefined.
Examples based on point 3
Example here shows arrow function called in two different ways.
var solarSystem = { name : "Solar System", getName : function() { console.log(this.name) // Solar System. var getInnerName = function() {
console.log(this.name) // undefined
}
var getNameUsingArrow = () => {
console.log(this.name); // Solar System
} getInnerName()
getNameUsingArrow()},
getName2 : () => {
console.log(this.name) // undefined
}}solarSystem.getName();
solarSystem.getName2();
As per rule 3 , whenever any arrow function is called , the this is bound to the outer scope / enclosing scope and not to the calling object . getNameUsingArrow() is called without any object. And getName2() is called with an object. But the this inside getNameUsingArrow() prints Solar System as the this in the outer scope points to the object as per rule 1. And in solarSystem.getName2() even if the calling object is solarSystem, the this is bound to the enclosing scope which is global. And hence prints undefined.
Long story short for arrow function :
- First find out the what is this pointing to in the outer function/enclosing scope. See carefully if the outer scope is global. (use rule 1 and rule 2 to find out)
- Once done, then simply say the this inside arrow function is equal to the this found in point 1.
Now that we know three typical use case. We will run through some quick objective questions. Use the rules stated above and guess your answer. Good luck !
Questions
Question 1:
var solarSystem = { getSolarObject: function() { console.log(this); }};solarSystem.getSolarObject()var fn_ref = solarSystem.getSolarObject;fn_ref();
Hint: think of rule 2 in case of fn_ref
Question 2:
function cricket_match(){ this.totalScore = 286; this.getTotalScore = function(){ console.log(this.totalScore) const innerfn = function(){ console.log(this.totalScore) } innerfn() }}var match1 = new cricket_match();match1.getTotalScore()
hint: how a method is called only decides this and not how the object was created.
Question 3:
function cricket_match(){this.totalScore = 434;this.getTotalScore = function(){ console.log(this.totalScore) const innerfn = () => { console.log(this.totalScore) } innerfn() }}var match2 = new cricket_match();match2.getTotalScore()
Question 4:
var obj = { bar: function() { var x = (() => this); return x; }};var fn = obj.bar();console.log(fn() === obj);var fn2 = obj.bar;console.log(fn2()() == window);
Question 5:
(asked in hotstar interview)
var x = 3;var char = 'A'var foo = { x: 2, foo: { x: 1, foo: function(){ char = 'B' return this.x } }}var go = foo.foo.foo;console.log(char, go(), foo.foo.foo());
Hope the explanation will help you get through all problems related to this. Comment if found any issue regarding explanation or problems. Will upload more questions. Thanks.