this keyword in javascript

See: this - JavaScript | MDN

1. this is the bound object on a calling method

something.foo()

Inside foo, this is bound to something.


2. A plain function call has no binding object

function greet() {
    console.log(this);
}

greet();

There is no object bound to the function to become this.

this === null                        // strict mode
this === window (or global object)   // not strict mode

Unbinding a method from an object has the same effect:

const person = {
    name: "Alice",

    greet() {
        console.log(this.name);
    }
};

const fn = person.greet;

fn();

3. Arrow functions inherit this from parent scope at definition time

class Person {
    constructor(name) {
        this.name = name;
    }

    greet() {
        setTimeout(() => {
            console.log(this.name);
        }, 1000);
    }
}

vs:

class Person {
    constructor(name) {
        this.name = name;
    }

    greet() {
        setTimeout(function () {
            console.log(this.name);
        }, 1000);
    }
}

Arrow functions inherit this from the greet function body this:

greet()
  │
  └── this = Person instance
          │
          └── arrow inherits this

The function definition is not bound to an object within greet and hence has undefined as its this


4. Classes: this refers to the current instance

class Person {
    constructor(name) {
        this.name = name;
    }

    greet() {
        console.log(this.name);
    }
}

const alice = new Person("Alice");

alice.greet();

5. You can explicitly choose this

You can delink class methods from the object.

The following does not work as expected since when the callback is called, the object context is lost and this becomes undefined:

button.addEventListener("click", alice.greet);

But this can be fixed by using ‘bind’:

button.addEventListener("click", alice.greet.bind(alice));

This reads as: “hand over the greet function as a callback BUT when you call it, use alice as this