How to Access the Correct “this” Inside a Callback?


In this tutorial, we will learn about how to Access the Correct “this” inside a callback.

“this” keyword

Each function contains a keyword called this, also known as “the context,” whose value is determined by how the function was called and not by how, when, or where it was defined. Unlike other variables, it is unaffected by lexical scopes. Compared to other languages, JavaScript acts a little differently when a function’s “this” keyword is used. Between strict mode and non-strict mode, there are several further changes.

How a function is called most often determines the value of “this” (runtime binding). It may change every time the function is called and cannot be changed by assignment while it is executed. The number of how a function is invoked, the bind() method can set this value since arrow functions don’t offer their own “this” binding (it retains the “this” value of the enclosing lexical context).

What is called a callback?

A function receiving an argument from another function is called a callback, often used later in the outer function. A higher-order function is a term used to describe the outer function that accepts a callback.

A callback has its own set of methods and properties because functions are objects in JavaScript. The “this” property allocated to a callback when executed inside a higher-order function relies entirely on how the callback is made, not where, how, or when it was defined.

By inspecting the higher-order function where a callback is invoked, we may determine the “this” value within the callback. The actual definition of the enclosing function may include locally scoped properties is the leading cause of the issues with this in callbacks. But because the context of the callback varies dynamically depending on how it is invoked, it doesn’t exist when that property is accessed via a “this” binding within the callback.

Now we will learn the methods for accessing the correct “this” inside a callback.

Using the “self” pattern

Making a variable called self and giving it the value of this in the scope where our function is declared is a typical pattern. We can achieve the desired behavior by creating a new variable called self (or any other valid variable name will work well) and giving it the value of “this”.

Example

<html>
<body>
   <h2> 'this' Inside a Callback using the <i> 'self' pattern </i> </h2>
   <button onclick="myFunction()"> Click here </button>
   <div id="root" style="
      background-color: rgb(240, 248, 255);
      border: 1px solid gray;
      margin: 5px 0px;
      padding: 10px;
   ">
      Welcome to Tutorialspoint!
   </div>
   <script>
      const root = document.getElementById('root')
      function myFunction() {
         this.variable = 'I am this variable'
         const variable = 'I am a const variable'
         const self = this
         setTimeout(() => {
            root.innerHTML = this.variable + '<br/>'
            root.innerHTML += variable
         }, 1000)
      }
   </script>
</body>
</html>

Using an arrow function

ECMAScript 6 saw the debut of JavaScript arrow functions. They don’t have their own binding and are the more concise alternative to a conventional function expression. This ensures that if this is referred to inside an arrow function, it is searched up in scope as a regular variable.

Example

<html>
<body>
   <h2> 'this' Inside a Callback using the <i> arrow function </i> </h2>
   <button onclick="myFunction('ABC')"> Click here </button>
   <div id="root" style="
      background-color: rgb(240, 248, 255);
      border: 1px solid gray;
      margin: 5px 0px;
      padding: 10px;
   ">
      Welcome to Tutorialspoint!
   </div>
   <script>
      const root = document.getElementById('root')
      function myFunction(name) {
         this.name = name
         let obj = {
            run: function(callback) {
               setTimeout(callback, 1000)
            },
         }
         obj.run(() => {
            root.innerHTML = this.name
         })
      }
   </script>
</body>
</html>

Using another variable to store the “this” object

The object links to it, which is typically what we truly want access to when we try to access this within a callback. Making a variable and storing its value right before the callback scope is one approach to accomplish this (although some programmers would rather not because it seems messy).

Some individuals refer to it as that or self, but as long as the terminology is clear-cut, it doesn’t matter. This workaround is effective since the variable complies with lexical scope requirements and is thus available within the callback. You still have access to whatever the callback’s dynamic this binding is, which is an added benefit of this way.

Example

<html>
<body>
   <h2>
      'this' Inside a Callback using the
      <i> another variable to store the 'this' object </i>
   </h2>
   <button onclick="myFunction('XYZ')"> Click here </button>
   <div id="root" style="
      background-color: rgb(240, 248, 255);
      border: 1px solid gray;
      margin: 5px 0px;
      padding: 10px;
   ">
      Welcome to Tutorialspoint!
   </div>
   <script>
      const root = document.getElementById('root')
      function myFunction(name) {
         this.name = name
         let that = this
         let obj = {
            run: function(callback) {
               setTimeout(callback, 1000)
            },
         }
         obj.run(function() {
            root.innerHTML = this.name
         })
      }
   </script>
</body>
</html>

Using explicitly binding this to an object

When we define a callback, we may state what we want this to be. We can set the “this” value using the bind() method and be sure that it will stay that way throughout the function’s execution regardless of how or where it is called or passed.

The bind() method is available in every function and creates a new function with the “this” property connected to a given object. The only difference between the returned and original functions is that you have complete control over what the “this” property points to.

Example

<html>
<body>
   <h2>
      'this' Inside a Callback using
      <i> explicitly binding this to an object </i>
   </h2>
   <button onclick="myFunction('Tutorialspoint')"> Click here </button>
   <div id="root" style="
      background-color: rgb(240, 248, 255);
      border: 1px solid gray;
      margin: 5px 0px;
      padding: 10px;
   ">
      Welcome to Tutorialspoint!
   </div>
   <script>
      const root = document.getElementById('root')
      function myFunction(name) {
         this.name = name
         let callbackFunction = function() {
            root.innerHTML = this.name
         }.bind(this)
         let obj = {
            run: function(callbackFunction) {
               setTimeout(callbackFunction, 1000)
            },
         }
         obj.run(callbackFunction)
      }
   </script>
</body>
</html>

Updated on: 06-Dec-2022

427 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements