Understand all about this keyword in JavaScript
The this keyword in JavaScript is very important concept but at the same time very confusing to understand.
In JavaScript, this keyword refers to the object it belongs to. It has different values depending on where it is used:
- In a method,
thisrefers to the owner object where method is defined. - Alone,
thisrefers to the global object. - In a function,
thisrefers to the global object. - In a function, in strict mode,
thisisundefined. - When a function called with new keyword,
thisrefers to new object instance - In a DOM event,
thisrefers to the element that received the event. - Function prototype methods call(), apply() and bind() can be used to refer
thisto any object.
this in a Method
When you execute a method of an object, this refers to the object where method is defined.
In the below example this refers to the person object since fullName() method is defined inside person object.
var person = {
firstName: "John",
lastName : "Doe",
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
console.log(person.fullName()); // John Doe
Let’s see one more example below where obj1 and obj2 are executing their own increment() methods so here this refers to obj1 and obj2 respectively
var increment = function(){
return console.log(this.a + 1);
}
var obj1 = { a: 1, increment: increment };
var obj2 = { a: 2, increment: increment };
obj1.increment(); //this = obj1
obj2.increment(); //this = obj2
Output
2
3
this Alone
When you use this alone, it refers to global object
Let’s try what is the value of this when used alone:
console.log(this); //this = window
Output
Window {parent: Window, opener: null, top: Window, length: 4, frames: Window, …}
We see that this refers to Window object, which is global object of browser.
Remember: In strict mode, when used alone, this also refers to the global object.
this in a Function (default)
For a function (which is at top level or not inside any function), this refers to global object.
function topLevelFunction(){
console.log(this);
}
topLevelFunction(); //this = window
In the above case this refers to the global object window of browser
this in a Function (strict)
However, for a function (which is at top level or not inside any function) in strict mode, this refers to undefined
Look at the below example where this refers to undefined in strict mode function:
'use strict';
function topLevelFunction(){
console.log(this);
}
topLevelFunction(); //this = undefined
one more example, where increment() function is called in strict mode, this refers to undefined and throw error.
var a = 1;
var increment = function(){
'use strict';
return console.log(this.a + 1);
}
increment(); //this = undefined
Output
Uncaught TypeError: Cannot read property 'a' of undefined
this with new
When a function is called using new keyword, then the function is known as a constructor function and returns a new object. In this case, this refers to a newly created object.
var Person = function(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
this.getFullName = function(){
console.log(`${this.firstName} ${this.lastName}`);
}
}
let person1 = new Person("Albert", "Einstein");
let person2 = new Person("Isaac", "Newton");
person1.getFullName(); //this = person1
person2.getFullName(); //this = person2
Output
Albert Einstein
Isaac Newton
this with Explicit binding
Function has call(), apply() and bind() prototype methods which can be called on function to change the context of this explictly.
Let’s look at these methods one by one and also see the differences
call()
ƒ.call(this, arg1, arg2, ...)
When a function is called using call() method,
- first argument is referred by
this - subsequent comma separated arguments are method arguments
Remember: “call() arguments are separated by commas”.
apply()
ƒ.apply(this, [arg1, arg2, ...])
When a function is called using apply() method,
- first argument is referred by
this - second argument is an array of values, are method arguments
Remember: “apply() accepts arguments as an Array”
bind()
ƒ.bind(this)
When a function is called using bind() method
- argument passed to bind() function is referred by
this - returns new bind function whose context is passed argument
Remember: “bind() method doesn’t call the function. It returns a new function which can be called later.
Let’s look at the example, how to use these three function prototype methods call(), apply() and bind()
let numObj1 = {num: 1};
let numObj2 = {num: 2};
let sumFn = function(...args){
console.log(this.num + args.reduce((a,b)=> a+b, 0));
}
sumFn.call(numObj1, 1, 2, 3, 4); //this = numObj1
sumFn.call(numObj2, 1, 2, 3, 4); //this = numObj2
sumFn.apply(numObj1, [1,2,3,4]); //this = numObj1
sumFn.apply(numObj2, [1,2,3,4]); //this = numObj2
let sumBindFn1 = sumFn.bind(numObj1); // return Fn
let sumBindFn2 = sumFn.bind(numObj2); // return Fn
sumBindFn1(1, 2, 3, 4); //this = numObj1
sumBindFn2(1, 2, 3, 4); //this = numObj2
output:
11
12
11
12
11
12