How to access “this” from inside a callback
Tags: javascript, scope, this
Published: 2019-04-19 18:18:11

---
title: How to access “this” from inside a callback
published: true
tags: JavaScript, scope, this
canonical_url: https://logicmason.com/2019/how-to-access-this-from-inside-a-callback/
---

JavaScript’s keyword `this` is a source of pain for a lot of people. A common question goes something like this:

> “I make call a Firebase function, and inside that callback, I need to access the this to update my React component.”

Another common case is setTimeout:

> “The problem is setTimeout takes a callback, but I need to access this and setTimeout changes it!”

## A basic guideline

In normal circumstances, `this` refers to whatever is to the left of the dot **at calltime**. There are a few exceptions, which specifically alter the behavior of this—`call`, `apply` and `bind`. If you haven’t used one of those functions to alter the behavior of this, then look to the left of the dot at calltime.

## An example

```js
var alarm = {
  ringer: function () {
    console.log("The " + this.color + " alarm: Ring!!!");
  },
  color: "red"
}

alarm.ringer();
```

This is pretty straight-forward. When you call `alarm.ringer();`, the thing to the left of the dot is `alarm`. So inside the ringer function, `this` is the alarm and the color is red.

## An error in a setTimeout callback

```js
var alarm = {
  ringer: function () {
    console.log("The " + this.color + " alarm: Ring!!!");
  },
  set: function (milliseconds) {
    setTimeout(function () { this.ringer() }, milliseconds);
  },
  color: "red"
}

alarm.set(2000);
```

The goal here was that the alarm would ring two seconds later. Unfortunately, we get this error:

![](https://logicmason.com/wp-content/uploads/2019/04/this-setTimeout.png)

The reason is that setTimeout calls the callback passed into it. Based on the error, we can see that the setTimeout function created a `Timeout` object and stored the callback function we passed into it as `Timeout._onTimeout`. And **at the time it was called** , the thing to the left of the dot is the timeout, not the alarm.

## The classic solution

The way the “this” problem has traditionally been solved is by assigning the “this” from the outer scope to a new variable called either “\_this” or “that”.

```js
var alarm = {
  ringer: function () {
    console.log("The " + this.color + " alarm: Ring!!!");
  },
  set: function (milliseconds) {
    var that = this;
    setTimeout(function () { that.ringer() }, milliseconds);
  },
  color: "red"
}

alarm.set(2000);
```

Now it works. Since the value of “this” inside the `set` function is the alarm, and `that` is just a regular variable. Since functions can access variables from their surrounding scope, `that.ringer()` inside the callback is `alarm.ringer()`.

```
The red alarm: Ring!!!
```

## The ES6 arrow function solution

ES6 arrow functions [don’t work quite the same way](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) as normal function expressions. They don’t have their own bindings to “this”, so any references to “this” use the bindings from the enclosing function.

```js
let alarm = {
  ringer: function () {
    console.log("The " + this.color + " alarm: Ring!!!");
  },
  set: function (milliseconds) {
    setTimeout(() => { this.ringer() }, milliseconds);
  },
  color: "red"
}

alarm.set(2000);
```

As the MDN link above mentions, arrow functions are ill-suited for methods, but they are a convenient way to simplify callbacks. In 2019, most JS devs use arrow functions to solve this problem and only encounter the “this = that” pattern in libraries and legacy code.

*Subscribe to more content from [logicmason.com](http://eepurl.com/diFSaf)*