`this` in JavaScript

Jan 3, 2020

The this keyword lets you reference the function's "execution context." That's a fancy way of saying that this refers to the object that a function is a property of when you call the function.

// `this` is an implicit parameter to the function
const fn = function() {
  return this;
};

// One way that `this` is set is by attaching the function
// to an object.
const obj1 = { fn };
const obj2 = { fn };

obj1.fn() === obj1; // true
obj1.fn() === obj2; // false

obj2.fn() === obj1; // false
obj2.fn() === obj2; // true

The important thing to note is that, since functions are plain old variables in JavaScript, this may change. One common way to mess up the value of this is to assign a function to an object and call the function without an associated object. This is informally known as the function losing its context.

const fn = function() {
  return this;
};

const obj = { fn };

// If you call `fn()` without a property access `.`, you're
// implicitly setting the function context to `null`.
const myFn = obj.fn;
myFn() == null; // true in strict mode

TLDR: this is an implicit parameter to a function call. It contains whatever object the function was a property of when it was called.

With Classes

You will often see this in ES6 class methods. In a class method, this refers to the instance of the object the method is called on.

class MyClass {
  myFunction() {
    return this;
  }
}

const obj = new MyClass();

obj.myFunction() === obj; // true

Arrow Functions

Arrow functions are special because, unlike other functions, they have lexical context. That means this in an arrow function is the same as this outside the arrow function, regardless of how you call the arrow function.

const arrow = () => this;

arrow() == null; // true

const obj = { arrow };

// Even though `arrow()` is attached to an object, it still
// has the same context as the surrounding block.
obj.arrow() == null; // true
obj.arrow() == this; // true

Using bind(), call(), and apply()

Every JavaScript function has a Function#call() function and a Function#apply() function that lets you set the value of this without explicitly attaching the function to an object. You can think of call() and apply() as letting you set the implicit parameter this explicitly.

There is also a Function#bind() function that creates a copy of the function with a pre-set context.

const fn = function() {
  return this;
};

const obj = {};

fn.call(obj) === obj; // true
fn.apply(obj) === obj; // true

const copy = fn.bind(obj);
copy() === obj; // true
copy === fn; // false

Did you find this tutorial useful? Say thanks by starring our repo on GitHub!

More Fundamentals Tutorials