Javascript has a special variable called this
, which points to the current execution context. The execution context is the environment a function or method is executed in.
The value of this
isn’t determined until run time. Since the same method or function can be executed in different contexts in the same program, the value of this
in can also change.
In a browser, logging this
in the global context logs window
, which is the global object. The value of this
can also be checked by comparing it to another value:
console.log(this === window); // true in the global scope
The value of this
inside an object is the calling object, meaning the object itself. For example,
var obj = {
prop: 5,
showProp: function() {
console.log(this.prop);
},
showThis: function() {
console.log(this);
},
}
obj.showProp(); // logs 5
obj.showThis(); // logs properties of obj
In the showProp
method, this
is used to refer to the current object obj
. If this
wasn’t used, it would look for a variable in the outer scope named prop
. If there’s no variable with that name in an outer scope, it throws an error.
Since this
is just a variable, it can be passed as an argument or returned from a function:
var obj = {
prop: function() {
return this;
},
};
var obj2 = {
log: function(arg) {
console.log(arg);
}
}
console.log(obj.prop()); // logs properties of obj
obj2.log(this); // logs window
We can also add a method to obj
which compares this
to the object:
obj.compareThis = function() {
console.log(this === obj);
};
obj.compareThis(); // logs true
Inside a method, this
refers to the calling object. What does this
refer to in a function?
function testThis() {
console.log(this);
}
testThis(); // logs window
That makes sense if testThis
was declared in the global scope, since testThis
would be equivalent to
window.testThis();
because functions declared in the global scope get added as properties to the window
object. What about this case:
var testThis = {
prop: function() {
(function() {
console.log(this);
})();
},
};
testThis.prop(); // logs window
This logs window
even though the inner function was called inside the testThis
object.
This is somewhere the distinction between a method and a function is important. In a method, this
refers to the calling object. In a function, this
refers to the global object unless an explicit context was supplied to invoke the function. The rules for defining this
are different than variable scoping.
As mentioned earlier, the value of this
can change when the execution context changes. For example,
var testThis = {
prop: function() {
console.log(this);
},
};
testThis.prop(); // logs properties of testThis
var extract = testThis.prop;
extract(); // logs window
This shows that when a method is taken from its original context and executed in a new context, this
will be the new context.
Javascript has the methods call
and apply
that let you execute a function in a context you specify. They work the same way except for how they pass optional arguments. You can use them like this:
function logThis() {
console.log(this);
}
var obj1 = {
prop: 'first',
};
var obj2 = {
prop: 'second',
func: function() {
console.log(this.prop);
},
};
obj2.func(); // logs 'second'
obj2.func.call(obj1); // logs 'first'
logThis.call(obj2); // logs the properties of obj2
This invoked a method from obj2
as if it belonged to obj1
. The last line invoked a function in an explicit context (obj2
) and it logs the properties of that object instead of window
.
To conclude all of this, this
is a variable that refers to the current execution context. Its value is assigned at run time. In an object method it points to the calling object. In a function, it points to the global object, which in a browser is window
.