this in JavaScript: understanding what it points to

In JavaScript, this does not depend on where a function is written but on how it is called: five calling forms produce five different results.
3 min read
Believemy logo

No keyword in the language causes as much confusion. The reason is simple: in most languages this is fixed when the code is written, whereas in JavaScript it is decided when the function is called.

The same function can therefore see several different values depending on how it is triggered.


Definition

this means the object a function is currently being called on. It is not the object the function is written inside, it is the one sitting to the left of the dot at the moment of the call.

JAVASCRIPT
const counter = {
  total: 0,
  increment() {
    this.total += 1;
    return this.total;
  },
};

console.log(counter.increment());   // 1
console.log(counter.increment());   // 2

Here counter sits to the left of the dot, so this means that object, and the increment really does land on it.


Five calling forms, five results

The table below reads as a grid: find the shape of the call, read the value you get.

Shape of the callValue of this
object.method()The object placed before the dot
fn() inside a moduleundefined
new Model()The instance being built
fn.call(target)The target passed as first argument
Arrow functionThe one from the surrounding code

The second row deserves a note: inside a module or in strict mode, a call with no object gives undefined. In an old script loaded outside module mode, the same line gives the global object.


The detached method trap

Storing a method in a variable, or passing it as an argument, cuts the link with its object. This is the most frequent source of errors around the keyword.

JAVASCRIPT
const counter = {
  total: 0,
  increment() { this.total += 1; return this.total; },
};

const detached = counter.increment;
try {
  detached();                 // nothing left of the dot any more
} catch (error) {
  console.log(error.name);    // TypeError
}

const bound = counter.increment.bind(counter);
console.log(bound());         // 1

The bind method builds a new function whose value is frozen for good. The other solution, often more readable, is to wrap the call in an arrow function: an arrow has no value of its own and reaches for the one in the surrounding code.

JAVASCRIPT
const timer = {
  seconds: 0,
  start() {
    setTimeout(() => {
      this.seconds += 1;
      console.log(this.seconds);   // 1
    }, 0);
  },
};

timer.start();

With a classic function in place of the arrow, the addition would produce NaN: setTimeout is what calls the function, with no object to the left of any dot.


Frequently asked questions

Question

Why does an arrow function have no this of its own?

Because it never receives one at call time: it uses the value from the code it is written in, exactly like any other variable of that code. That makes it ideal inside a method, and unsuitable for defining a method itself, where it would reach for a value that does not exist.


Question

What is the difference between call, apply and bind?

call and apply invoke the function immediately while forcing the value, the only difference being how arguments are passed, one by one or inside an array. bind invokes nothing: it returns a new function with the value frozen, to trigger later.


Question

How do I work out what this means in code I am reading?

Do not look at the function declaration, look for the call. The question is always the same: what sits to the left of the dot at the moment the function is triggered. Our JavaScript course spends real time on this mechanism, because it governs how you read any object-oriented code.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.