What is "this" behavior JavaScript ?
Eliminate your fears and doubts about this keyword in JavaScript.
Introduction
In JavaScript, this keyword behaves a little differently than in other languages .There are also some distinctions between value of this keyword in strict and non-strict modes .The value of this is usually calculated by how a function is defined (runtime binding), in non–strict mode, it is always a reference to an object and in strict mode can be any value.
Following are five different scenarios to keep in mind.
Global context / Default Binding
This refers to the global object, whether in strict mode or not, in the global execution sense (outside of any function).
function foo(){
this.a = 'foo';
console.log(this);
}
foo();
When calling a function in a standard way shown above, “this” will actually refer to the Global object! In the browser the Global object means the Window object.
Implicit Binding
If the function is contained within an object then that object will will be referenced by “this”. In the following example, when o.f() is invoked, inside the function this is bound to the o object.
var o = {
prop: 37,
f: function() {
return this.prop;
}
};
console.log(o.f()); // 37
Derived classes/New Binding
When an instance of an object is created using the new keyword, “this” is always set to that same instance.
var MyObject = function (){
this.name = 'MyObjectName';
this.myProperty = 'property';
};
MyObject.prototype.doStuff = function (action) {
console.log(this.name + ' is ' + action + '!');
}
var obj = new MyObject();
obj.doStuff('awesome'); // prints 'MyObjectName is awesome!'
Explicit Binding
Explicit binding of this occurs when .call(), .apply(), or .bind() are used on a function. We call these explicit because you are explicitly passing in a this context to call() or apply(). For .call() we pass in the this we'd like to use, along with parameters. For example, using the object declared above
var runner = { name: 'John', myFavoriteActivity: 'running' };
MyObject.prototype.doStuff.call(runner, runner.myFavoriteActivity); // prints 'John is running!';
Since we have .call, we must ignore what appears before the dot in our function call. We are using MyObject's method and calling it on another this context: runner.
.apply() is almost the same, except we must pass in an array of parameters after our this context.
myFunc.apply(thisContext, [param1, param2, ...]);
.bind()
bind() complicates matters a bit when called on a function, .bind() sets a this context and returns a new function of the same name with a bound this context. For example:
var sayMyName = function () {
console.log('My name is ' + this.name);
};
var jake = {
name: 'Jake'
}
var sayMyName = sayMyName.bind(jake);
sayMyName(); // 'My name is Jake'
Now, each time we invoke sayMyName, we will get the context of 'jake', because this has been bound to it.
Arrow functions
In arrow functions, this retains the value of the enclosing lexical context's this. In global code, it will be set to the global object:
var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true
This is obviously a rather brief overview of the "this" keyword, but it should suffice to highlight the main points.