Default Binding of the this keyword in JavaScript
Understand the default binding of the this context in JavaScript
Table of contents
Have you ever wondered what is your this
context? In this article, we will learn about finding our Nemo i.e. the this
context in the case of default binding.
But before that, letโs have a primer on implicit and explicit bindings.
Implicit and Explicit Binding Primer
We can bind our this
context either implicitly OR explicitly. You can read more about them in my What is this in JavaScript article.
In short, implicit binding happens when we call a this
aware function with an object like this, where in the call site the eat
function is invoked using the restaurant
object:
var restuarant = {
food: "๐๐๐",
eat() {
console.log(`I'm eating ${this.food}`);
},
};
// Implicit binding
restuarant.eat(); // I'm eating ๐๐๐
Whereas, explicit binding happens either by using the new keyword OR by using a binding method on a function like call
OR apply
. The bind
method internally uses apply
method so it also does the explicit binding.
var restuarant = {
food: "๐๐๐",
eat() {
console.log(`I'm eating ${this.food}`);
},
};
// Using the call method
restuarant.eat.call({ food: "๐๐๐" }); // I'm eating ๐๐๐
// Using the apply method
restuarant.eat.apply({ food: "๐ฅช๐ฅช๐ฅช" }); // I'm eating ๐ฅช๐ฅช๐ฅช
// Using the bind method
var eat = restuarant.eat.bind({ food: "๐ฎ๐ฎ๐ฎ" });
eat(); // I'm eating ๐ฎ๐ฎ๐ฎ
Default Binding
When a function is invoked not using methods that cause implicit and explicit bindings, the fallback is default binding. In the non-strict mode, it will default to the global object. Whereas, in the strict mode, it will be undefined
.
The reason for this
being undefined
in the strict mode is that itโs a terrible idea to have this
when you havenโt bonded the function to any context.
var food = "๐๐๐";
function inNonStrictMode() {
console.log(`I am eating ${this.food}`);
}
function inStrictMode() {
"use strict";
console.log(`I am eating ${this.food}`);
}
inNonStrictMode(); // I am eating ๐๐๐
inStrictMode(); // TypeError: Cannot read properties
// of undefined (reading 'food')
Note that this.food
for the inNonStrictMode
function will be ๐๐๐
when you execute this code in the browser where the global context will be the window object.
In Node.js, this.food
for the inNonStrictMode
function will be undefined
. The reason for this is that Node.js wraps your script into a function and executes it. Something like this:
(function (exports, require, module, __filename, __dirname) {
var food = "๐๐๐";
function inNonStrictMode() {
console.log(`I am eating ${this.food}`);
}
function inStrictMode() {
"use strict";
console.log(`I am eating ${this.food}`);
}
inNonStrictMode(); // I am eating ๐๐๐
inStrictMode(); // TypeError: Cannot read properties of undefined (reading 'food')
})(exports, require, module, "file.js", "/dir/name");
Since a function has a this
context, we use that context when we say this.food
and since that this
doesnโt have a food
property, we get undefined
. Read more on this in this StackOverflow article.
This also makes one thing clear, you cannot figure out the this
context by looking at either the function definition OR by the โcall siteโ. The manner in which the function is invoked i.e. the real call site will determine the this
context.
Conclusion
Never use the this
context when you havenโt bonded your function with one, either implicitly OR explicitly. Itโs a ๐ฉ big sin.
If you liked this post then do ๐๐ป clap and give your ๐ feedback. Follow me to learn more about such topics.