Intro
A short blog about how you can determine the values of this keyword.
A confusing js concept (at least for me), Kyle Simpson and his book series "You don't know JS" made it more clear to me.
I hope that the following blog might help you to understand how this keyword works (I hope the same for myself :) ).
What is a this
In order to understand the this keyword, a good start is to get rid of what you know about this keyword in any other languages.
Now, in js each function when is executed has an execution context, you get access to this execution context by using the this keyword (so it is an execution context).
How you can determine the this
In order to determine the values/properties (bindings) that the this keyword has, you need to know two things:
- where the function was called (location)
- How the function was called
let's see how the ''this'' properties are determined (context bindings).
(All the context determination happens at the runtime).
Default binding
Default binding is the simplest form, you just invoke the function from the global scope/object (window).
function findThePlayer() {
console.log(this.player);
}
var player = "Tsimikas: left back";
findThePlayer();
Determination procedure:
- From where the function called? from the global scope
- how? just a simple call
- From 1 and 2, we determine that the execution function context is the global context
- global scope has a player variable definition, so this has also a binding to that player
Kostas Tsimikas is printed!!
Implicit binding
In the Implicit binding, the execution context is determined from the object (e.g. the call would look like object.function()).
function findThePlayer() {
console.log(this.player);
}
var player = "Kostas Tsimikas: left back";
var iniesta = {
player: "Andres Iniesta: midfielder",
findThePlayer: findThePlayer
};
iniesta.findThePlayer(); // implicit binding, Andres Iniesta: midfielder
Determination procedure:
- From where the function called? from the global scope
- how? the function call made by using an object reference
- The execution context is the object (e.g. iniesta), isn't the global (explicit binding takes precedence over the default binding)
Andres Iniesta: midfielder, is printed!!
If we had invoke the function without the object, the output would be, Kostas Tsimikas: left back
Explicit binding
In the Explicit binding, the execution context is directly assigned by passing the context to call() function
(e.g. the call would look like function.call(context)).
function findThePlayer() {
console.log(this.player);
}
var iniesta = {
player: "Andres Iniesta: midfielder"
};
var mane = {
player: "Sadio Mane: forward"
};
findThePlayer.call(iniesta);
findThePlayer.call(mane);
Determination procedure:
- From where the function called? from the global scope
- how? both functions are performed by assigned the context directly (e.g. iniesta and mane)
- The execution context in both cases is the context that we pass explicity by using the call() function (explicit binding takes precedence over the default binding)
new binding
In the new binding, a whole new context is created. Just by calling a function with the new keyword.
function player(name) {
console.log(this.giovanni);
this.name = name;
}
var giovanni = "Giovanni Silva De Oliveira";
var messi = new player("Lionel Messi: forward");
console.log(messi.name);
- From where the function called? from the global scope (doesn't matters in this case)
- how? function called by the new keyword
- In this case a new whole this is generated
In the above example, when you try to print the giovanni variable you are getting the value undefined.
This happens due to the use of the new keyword.
explicit vs implicit binding
When you invoke a function by using an object and explicitly specifying the context (e.g. using call() function),
the the execution context would be the context that you have assigned in the call().
function findThePlayer() {
console.log(this.player);
}
var iniesta = {
player: "Andres Iniesta: midfielder",
findThePlayer: findThePlayer
};
var mane = {
player: "Sadio Mane: forward",
findThePlayer: findThePlayer
};
iniesta.findThePlayer.call(mane);
The above script will print Sadio Mane: forward (explicit bind wins implicit)
To sum up
how to determine the this:
- if there is a new keyword in the function call, a new execution context is created
- Explicit binding: calling a function using the call function and providing the execution context
- Implicit binding: calling a function using an object, the execution context is the object
- simple function call, the execution context is determined by the location that the function was invoked
- Explicit wins implicit
Cheers!
Top comments (0)