This

This & Its Contexts

In JavaScript this keyword is a reference to an object in the context of which JavaScript statements and expressions are being interpreted at a given moment. this can be invoked at all times however - in some circumstances - its value may be undefined.

As noted, the value referenced by this depends on the execution context. The following contexts are relevant for the value referenced by this:

  • Global Context

  • Non-strict-mode Non-arrow Global Function Context

  • Strict-mode Non-arrow Global Function Context

  • Non-arrow Non-global Method Function Context

  • Constructor Context

  • Class Context

  • DOM Event Handler Context

  • Bound Context

  • Arrow Function Context.

Global Context, Non-strict-mode Non-arrow Global Function Context, and Strict-mode Non-arrow Global Function Context can be jointly referred to as the Default Context. Non-arrow Non-global Method Function Context, Constructor Context, Class Context, and DOM Event Handler Context can be jointly referred to as the Implicit Context. Bound Context can be referred to as the Explicit Context. And, Arrow Function Context can be referred to as the Lexical Context.

Global Context

In the global context this refers to the global object.

console.log(this) // Window {window: Window, self: Window ...

// Functions declared in the global context and variables declared with 'var' in the global context become properties of the global object.
var theNumber = 42
console.log(this.theNumber) // 42

Non-strict-mode Non-arrow Global Function Context

When the strict mode is not enabled and a function is called as a global function then the value referenced by this is the global object.

function logThis() {
  console.log(this)
}

logThis() // Window

Strict-mode Non-arrow Global Function Context

When the strict mode is enabled and a function is called as a global function then the value referenced by this is undefined.

function logThis() {
  'use strict'
  console.log(this)
}

logThis() // undefined

Non-arrow Non-global Method Function Context

When a non arrow function is called as a non-global object's method then the value referenced by this within that function body is that object.

const anObj = {
  foo: 42,
  bar: function() { console.log(this) }
}

anObj.bar() // {foo: 42, bar: ƒ}

Constructor Context

When a function is called with new keyword this becomes a reference to the object that is being created as a result of that call.

function Horse(name) {
  this.name = name
  console.log(this.name)
}

const geraltsHorse = new Horse('Roach') // Roach
const cirisHorse = new Horse('Kelpie') // Kelpie

Class Context

In the class context this refers to an object being a specific instance of a class.

class Animal {
  constructor(name) {
    this.name = name
    console.log(this)
  }
}

new Animal('Roach') // Animal {name: "Roach"}
new Animal('Kelpie') // Animal {name: "Kelpie"}

Derived classes instances (i.e. instances of classes that extend other classes) do not have the initial this binding. The super() idiom needs to be used to be able to reference this in derived classes instances.

DOM Event Handler Context

Within a DOM event handler this references the HTML element that is the receiver of the event.

<button onclick="function() { console.log(this) }">
</button>

Bound (Explicit) Context

It is possible to bind a specific this reference within a given function. There are three ways to achieve this: apply, call and bind. apply and call - in addition to binding a specific value to this reference - call the function. bind only binds the this reference to a specific value but does not call the function and instead returns the function object itself.

Arrow Function (Lexical) Context

this within the body of an arrow function retains the reference to the value of the enclosing lexical context irrespective of whether the function is a non-global method or not.

const anObj = {
  foo: 42,
  bar: () => { console.log(this) }
}

anObj.bar() // Window
class Animal {
  constructor(name) {
    this.name = name
  }
  logName = () => console.log(this.name)
}

const samsPony = new Animal('Bill')
samsPony.logName() // Bill

Context Precedence

The value referenced by this is set observing the following context precedence: 1) Constructor Context, 2) Bound Context, 3) Non-arrow Method Context, 4) Class Context, 5) Non-arrow Global Function Context, and 6) Global Context.