In this blog post we will take up one of the most interesting
topic in Javascript. Please read this blog post with caution as it comes with a
disclaimer.
"this" blew my brains out.......
For all of those like me who are coming to Javascript from any 4G
language would know that this refers to the current
instance of the object. So say we have a class Employee and we created its
instance _employee, now inside any function defined in Employee this will
refer to the current instance(_employee).
Well lets say in terms of Javascript above statement is only a
part of the truth. In Javascript this is refers to much
more. To begin with it this inside a function refers to
the object which invoked the function where this is
used.
So lets try to make sense of above statement, fire up the chrome
console and emit out following snippet.
var person = {
firstName: 'Bond',
lastName: 'James',
showName: function () {
console.log('Name is ' + this.firstName + ' ' + this.lastName + ' ' +
this.firstName);
}
}
person.showName();//Name
is Bond James Bond
1st Golden Rule:
this refers
to the value of the object that invoked the function using this.
In the example above person invoked the function (showName) and
thus this inside showName points to person.
firstName = 'Alpha';
lastName = 'Beta';
var person = {
firstName: 'Bond',
lastName: 'James',
showName: function () {
console.log('Name is ' + this.firstName + ' ' + this.lastName + '
' + this.firstName);
}
}
//called in
context of person
var callfunc =
person.showName(); //Name is Bond James Bond
function
showName() {
console.log('Name is ' + this.firstName + ' ' + this.lastName + ' ' +
this.firstName);
}
//called
function from global context
showName();
//Name is Alpha Beta Alpha
2nd Golden Rule
this of outer function is
not accessible to inner function (for that matter both this and argument of
outer function are not accessible to the inner function) , it
basically points to the global object
var
name="pankaj";
var outer={
name:"lala",
getNameFunc : function(){
return function(){
return this.name;
};
},
getFunc : function(){
return this.name;
}
};
console.log(outer.getNameFunc()());
//pankaj
console.log(outer.getFunc());
//lala
A bit confusing thus deserve a bit of explanation. Since getNameFunc
was invoked with reference to outer we would expect this inside of getNameFunc
to refer to outer only and thus lala should be available to same.
Unfortunately this is one of those things in Javascript which is let’s
say interesting. I remember getting into discussion with one of my peer if this
is a feature of Javascript of behaviour the debate got all heated up until Douglas
Crockford came to my rescue.
In his book Javascript the good parts he did mentions that this is
a mistake in design of the language, had the language been designed correctly,
when the inner function is invoked, this would still be bound to the this variable
of the outer function.
A very common workaround for correcting this behaviour is to
preserve this of outer function and in the inner function use same instead of
this. Doing this will ensure that in which ever context the call is made inner
function will always refer to the context of the outer function.
var
name="pankaj";
var outer={
name:"lala",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
},
getFunc : function(){
return this.name;
}
};
console.log(outer.getNameFunc()());
//pankaj
console.log(outer.getFunc());
//lala
I will explain later why as per me this is a workaround.
Its worth mentioning that a function which is part of an object (which again is a function), it known as the method of the object
3rd Golden Rule
When a method is assigned to a variable, this belongs to the global context
var name ='Pankaj';
var Person ={
name:'Lala',
getName: function(){
return this.name;
}
}
//getName invoked within context of Person
console.log(Person.getName()); //Lala
//capture the reference of getName in local var
var func = Person.getName;
// getName gets invoked with the context of global
console.log(func()); // Pankaj
4th Golden Rule
For borrowed method, this belongs to the new object
var SimpleCaclulator={
num1:5,
num2:5
}
var ComplexCalculator={
num1:10,
num2:20,
add:function(){
return this.num1+ this.num2;
}
}
console.log(ComplexCalculator.add()); //30
SimpleCaclulator.add = ComplexCalculator.add; // attching add to SimpleCaclulator
console.log(SimpleCaclulator.add()); // 10 this belongs to SimpleCaclulator
Summary
These sums up the quirks with this in Javascript. We looked at what this means in Javascript, how it should be used.
We also learned the workaround to avoid falling into these quirks, to mention in coming posts we should be taking about the standard ways to avoid these situations.
Till then 'this' is it.