How to Access the Correct 'this' Inside a JavaScript Callback?

  1. Use ES6 arrow functions:

One of the simplest ways to access the correct “this” inside a callback is to use ES6 arrow functions. Arrow functions are essentially anonymous functions that don’t change the value of “this” and always point to the outer lexical scope. This means that you don’t have to worry about using call or apply to bind the function to the object.

Here’s an example:

class Foo {
  constructor() {
    this.bar = 'bar';
  }
  doStuff() {
    setTimeout(() => {
      console.log(this.bar);
    });
  }
}
  1. Use the bind() method:

If you don’t prefer to use ES6, another alternative is the “bind()” method that you can use to bind the function to a specific object. With bind(), you’re creating a new function from an existing one while also setting the “this” keyword to the desired value. Here’s an example:

const obj = {
  x: "Hello There",
  foo() {
    console.log(this.x)
  }
}

setTimeout(obj.foo.bind(obj), 1000);
  1. Store “this” in a variable:

Another method is to store the required value of “this” in a variable outside the callback and then reference that variable inside the callback. Here’s an example:

class Foo {
  constructor() {
    this.bar = 'bar';
    const self = this;
    setTimeout(function() {
      console.log(self.bar);
    }, 1000);
  }
}
  1. Use the call() or apply() method:

The “call” and “apply” methods allow you to call a function with a given value of “this”. The difference is that “apply” accepts an array of arguments, while call() accepts multiple parameters. Here’s an example:

const obj = {
  x: "Welcome to the blog.",
  foo() => {
    console.log(this.x);
  }
}

setTimeout(obj.foo.call(obj), 1000);
  1. Use callbacks designed specifically to solve this issue:

Some libraries, like jQuery, have their own ‘proxy’ functionality that is designed to solve this specific problem. “$.proxy” method creates a new function that has “this” pre-bound to the object you pass as context. Here’s an example:

const obj = {
  x: "Hello World",
  foo() => {
    console.log(this.x);
  }
}

setTimeout($.proxy(obj.foo, obj), 1000);

Conclusion:

Callbacks are a prominent part of the JavaScript ecosystem, but understanding how to access the correct “this” inside them can add complexity to them. We’ve seen some approaches to solve this problem, including arrow functions, bind(), variable setting, and even specialized libraries like jQuery. It’s important to practice and understand each method so that you can become a more competent developer. This skill will make your break points easier to find as well as promote both your and your organization’s reputation.