logo

What Does 'this' Mean in JavaScript?

Michael Morales  -  May 1, 2022  -  ,  

Let's look at a very comparable notion in the English language called polysemy to see what this really implies in JavaScript.

Take the word "ran" for example. Run is a single word that can indicate a variety of things depending on the situation.

"I'll run home" – means to run swiftly on foot. "She ran the 1500m" – means to compete in a race; "He's running for president" – means to run for a public office.

"The app is running" denotes that the software program is still open and functional.

"Go for a run" - this refers to running as a kind of exercise, and so on.

When you utilize this keyword in JavaScript code, an identical issue occurs. Depending on the context in which it was defined, it will automatically resolve to an object or scope.

What are the various scenarios? And how can we utilize that data to figure out which object this call will return?

This Context

‘this’ keyword merely points to an object to which it is bound when used in a function. It provides a response to the issue of where it should obtain some value or data:

function alert() { 

  console.log(this.name + ' is calling'); 

}

The keyword in the function above refers to an object to which it is bound. Therefore, the "name" property is obtained from there.

But how can you figure out which object the function is associated with? How do you figure out what this is about? To do so, we examine how functions are tied to objects in great detail.

Types of JavaScript Binding

There are four types of bindings in general:

  • Default Binding
  • Implicit Binding
  • Explicit Binding
  • Constructor Call Binding

Default Binding in JavaScript

One of the fundamental principles to remember in JavaScript is that if the function that has this reference is a standalone function, it is tied to the global object.

function alert() { 

  console.log(this.name + ' is calling'); 

}

const name = 'Kingsley'; 

alert(); // Kingsley is calling

As you can see, name() is a stand-alone function that is bound to the global scope. As a result, this name reference resolves to const name = 'Kingsley' in the global variable. If name() is defined in strict mode, however, this rule does not apply:

function alert() { 

  'use strict'; 

  console.log(this.name + ' is calling'); 

}

const name = 'Kingsley'; 

alert(); // TypeError: `this` is `undefined`

This reference is set to undefined while in strict mode.

JavaScript's Implicit Binding

Another thing to look for at the call location is whether the function is attached to an object (its context).

A function can only utilize an object as its context if it is bound to it at the call location, according to the binding rule in JavaScript. Implicit binding is the name for this type of binding.

Here's what I'm talking about:

function alert() { 

  console.log(this.age + ' years old'); 

}

const myObj = {

  age: 22,

  alert: alert

}

myObj.alert() // 22 years old

Simply put, when you use dot notation to invoke a function, the function is implicitly bound to the object from which it is called. This keyword is tied to myObj in this example because an alert is called from myObj. Here, age is 22, which is the age property of myObj, when an alert is called with myObj.alert().

Consider the following scenario:

function alert() { 

  console.log(this.age + ' years old'); 

}

const myObj = {

  age: 22,

  alert: alert,

  nestedObj: {

    age: 26,

    alert: alert

  }

}

myObj.nestedObj.alert(); // 26 years old

This is inherently connected to nestedObj instead of myObj because the alert is ultimately called from nestedObj.

Looking at which object is to the left of the dot (.) is a straightforward approach to figure out which object this is implicitly tied to:

function alert() { 

  console.log(this.age + ' years old'); 

}

const myObj = {

  age: 22,

  alert: alert,

  nestedObj: {

    age: 26,

    alert: alert

  }

}

myObj.alert(); // `this` is bound to `myObj` -- 22 years old

myObj.nestedObj.alert(); // `this` is bound to `nestedObj` -- 26 years old

Explicit binding in JavaScript

We observed that implicit binding was dependent on the object having a reference to it.

But what if we want a function to use an object as its context without referencing the object with a property function reference?

To accomplish this, we have two utility methods: call() and apply ().

These two utilities, along with a couple of other utility functions, are available to all JavaScript functions via the [[Prototype]] mechanism.

To explicitly bind a function call to a context, simply call the function with the context object as a parameter and pass it in:

function alert() { 

  console.log(this.age + ' years old'); 

}

const myObj = {

  age: 22

}

alert.call(myObj); // 22 years old

Now comes the exciting part. Even if you pass that function around to new variables numerous times (currying), every invocation will utilize the same context because it is locked (explicitly tied) to that object. This is referred to as hard binding.

function alert() { 

  console.log(this.age); 

const myObj = { 

  age: 22 

}; 

const bar = function() { 

  alert.call(myObj); 

}; 

bar(); // 22

setTimeout(bar, 100); // 22 

// a hard-bound `bar` can no longer have its `this` context overridden 

bar.call(window); // still 22

Hard binding is a good technique to bind context to a function call, turning it into a method.

Constructor Call Binding in JavaScript

The final and possibly most intriguing type of binding is the constructor binding, which emphasizes JavaScript's unique behavior in comparison to other class-based languages.

The following happens when a function is called with the new keyword in front of it, also known as a function Object() { [native code] } call:

  1. A completely new item is formed (or constructed)
  2. The newly created object is related to the function that created it via [[Prototype]].
  3. This binding for that function call is set to the freshly generated object.

To better understand this, let's look at it in code:

function giveAge(age) { 

  this.age = age; 

const bar = new giveAge(22); 

console.log(bar.age); // 22

We've generated a new object and set it as the this for the call of foo by executing giveAge(...) with new in front of it (...). This is the final technique to bind a function, and it's brand new.

Final Thoughts

This keyword ties the function to a context object when used in a function. Default binding, implicit binding, explicit binding, and function Object() { native code } call binding are the four types of bindings (new). Knowing these four guidelines will make determining the context for this reference much easier.

If you are a programming geek, here’s an article for you on how to get a computer programming job.

OUR BLOG
Strangler Fig Pattern
Strangler Fig Pattern
Any codebase that is old enough will ultimately contain legacy code. The moment architecture, performance, and comments are written, they ...
What is Web3?
What is Web3?
You are a participant in the modern web if you are reading this. The internet we use is very different ...
What Does 'this' Mean in JavaScript?
What Does 'this' Mean in JavaScript?
Let's look at a very comparable notion in the English language called polysemy to see what this really implies in ...
1 2 3 29
logo
J-sim's goal is to be one of the broadest online sources of content for Computer Technology, Internet Security, and anything within the World Wide Web. We aim to provide the information and tools needed to help enhance our readers' minds when it comes to today's technological advancements.
Copyright © 2022 j-sim. All Rights Reserved.
DMCA.com Protection Status