Understanding ‘this’ keyword in javascript
Guess the output of below code snippet:
var truck1 = {
sound: ‘putputput’,
driveMyTruck: () => {
return this.sound }
}
this.sound = ‘blahblahblah’;
console.log(truck1.driveMyTruck());
Output
blahblahblah
Quiet shocing right!!
Now guess the output of the following one:
const truck1 = {
sound: ‘putputput’,
driveMyTruck: function() {
return this.sound;
}
}
this.sound = ‘blahblahblah’;
console.log(truck1.driveMyTruck());
Output:
putputput
What exactly is the difference between two code snippets?
Answer: driveMyTruck is an arrow function in the first snippet.
Now let's start our research on ‘this’ in javascript.
The this keyword gets automatically defined in the scope of every function and it’s binding happens in three ways — default, implicit and explicit.
Implicit Binding
const person = {
name: 'Alex',
greet() {
console.log('Hey my name is ' + this.name)
}
}person.greet() // Hey my name is Alex
Explicit Binding
There is a solution to explicitly say to a function what object it should use for this — using functions such as call, apply and bind.
The call function allows you to pass in the object to which the this keyword should be bound to. It also allows you to pass arguments for the function as additional parameters.
function greet() {
console.log( this.name );
}var person = {
name: 'Alex'
};greet.call( person, arg1, arg2, arg3, ... ); // Alex
The apply function is similar to call with the difference that the function arguments are passed as an array or an array-like object.
function greet() {
console.log( this.name );
}var person = {
name: 'Alex'
};greet.apply( person, [args]); // Alex
The bind function is a little bit different than the first two. It creates a new function that will call the original one with this bound to whatever was passed in.
function greet() {
console.log( this.name );
}var person = {
name: 'Alex'
};var greetPerson = greet.bind( person );
greetPerson(); // Alex
‘this’ in arrow function
Arrow functions do not bind their own this
, instead, they inherit the one from the parent scope, which is called "lexical scoping". This makes arrow functions to be a great choice in some scenarios but a very bad one in others.
Let's start with simple examples:
- const myFunction = () => {
console.log(this);
};
// call it
myFunction(); //prints Object:{} - const myObject = {
myMethod: () => {console.log(this);}
};
this.sound = “rararara”
myObject.myMethod(); //print Object:{sound:”rararara”}
Here it is clear that arrow function myMethod got the global context. - const myObject = {
myArrowFunction: null,
myMethod: function () {
this.myArrowFunction = () => { console.log(this) };
} };
myObject.myMethod() // this === myObject