"this" is it !!
“this” keyword is the most confusing & punishing of Javascript community as a slight miss may results in blocker bugs and developers ending their time in debugging stack-traces, which could have been avoided.
This post talks about the use of “this” and tries to clear the concept by live examples. Before trying out codepen link please try to answer the code block and then see the explanation.
So JS Ninjas, let me ask you this simple question.
What do you think the output of all the expression ( Look for // ?)
var fii = {
name : ‘User-1’,
print : function () {
document.write(“<br/>”+this.name);
}
}
fii.print(); // ?
var fii1 = {name: ‘User-2’, print : fii.print};
name = ‘User-3’;
fii1.print(); // ?
fii.print(); // ?
var fii2 = fii.print;
fii2(); // ?
CodePenLink : https://codepen.io/avinash8526/pen/ZxXjOq/
If you were correct against all the // ?, then congrats you have a good understanding about “this”, for those who were wrong (including myself),lets go step by step in context with line numbers.
Line 8:
It calls the print method and prints User-1 , here “this” refers to the object itself. This is also called implicit binding and “this” is attached to Object “fii”.
Line 14:
Here Object “fii1” print method refers to the print method of Object “f11”, but again implicit binding rule applies and the calling object “fii1” name value gets printed.
Line20:
This may be slight confusing, here “fii2” refers to the print method of “fii1” but when it gets called it’s scope is global and in global scrope name variable has value “User-3”. In this case default binding rule applies which says in non strict mode “this” is window object and in strict mode it is “undefined”.
Now let’s go through another example:
function printJedi(){
var name = “Obi-Wan”;
printSecure();
}
function printSecure(){
document.write(this.name); // ?
}
var name=”Anakin”;
printJedi();
What do you think the output will be //?
CodePendLink:- https://codepen.io/avinash8526/pen/NYwawx
For those who think it is “Obi-Wan” you guys just missed it.. Remember the rule, “this” becomes the calling context by default binding rule and it this case when it is called context was “window” and in that context name is “Anakin” so the final output will be “Anakin”
I guess now at this stage we are clear about implicit and default binding rule. Lets dive to another concept with this example:
function printScreenSize(){
document.write(“<br/>”+this.deviceSize);
}
var deviceSize = ‘1024 x 720’;
printScreenSize(); // ?
var mobile = {deviceSize : ‘640 x 320’};
printScreenSize.call(mobile); // ?
.call is another way to call a function but we can pass the context, which in this case is “mobile” object hence the explicit binding rule overrides the default and implicit binding rule. (Read about .apply it is same as .call with difference in the way arguments are passed.)
Now since we have covered most of it I am sure everyone will answer correctly the below snippet.
function whoAmI(){
document.write(this.name); // ?
this.name = “Joker”;
}
var name = “King”;
new whoAmI();
So what will document.write spit out ? King of-course.
Naah // It will print undefined, why ? because we called that function with constructor call. Adding new keyword creates a new “this” object and assigns the value. Try printing new WhoAmI().name; So be careful whenever the function is called via new keyword.
CodePen https://codepen.io/avinash8526/pen/eMeeMb
Lets come to final section of the page and look at this code snippet
name = ‘User-3’;
var fii = {
name : ‘User-1’,
print : () => {
document.write(“<br/>”+this.name);
}
}
fii.print(); // ?
var fii1 = {name: ‘User-2’, print : fii.print};
fii1.print(); // ?
fii.print(); // ?
var fii2 = fii.print;
fii2(); // ?
CodePenLink : https://codepen.io/avinash8526/pen/JLOOqY
This code snippet is similar to first one and I am sure you all have answered it correctly :) If not read about arrow functions…