# JavaScript this Keyword: Binding Rules and Contextual Behavior

> Master the JavaScript this keyword. Understand its binding rules and contextual behavior, from constructor calls to default binding and lexical scope with arrow functions. Optimize your code.

- Repository: [Kyle Simpson/You-Dont-Know-JS](https://github.com/getify/You-Dont-Know-JS)
- Tags: deep-dive
- Published: 2026-02-24

---

**TLDR:** The `this` keyword is an implicit parameter that JavaScript functions receive at runtime, with its value determined entirely by how the function is invoked—following four precedence rules from constructor (`new`) down to default binding—while arrow functions capture `this` lexically from their surrounding scope.

The `this` keyword is one of JavaScript's most misunderstood features. According to the **You-Dont-Know-JS** repository by Kyle Simpson, `this` is not an author-time binding but a runtime mechanism that depends strictly on the call-site. Understanding these binding rules—as detailed in **[objects-classes/ch4.md](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/objects-classes/ch4.md)**—is essential for mastering object-oriented patterns and avoiding common context-related bugs.

## What Is the `this` Keyword in JavaScript?

In JavaScript, `this` is an **implicit parameter** that the engine supplies to every function containing the identifier. Its value is **not fixed at author-time**; instead, it is determined **at run-time** by **how the function is invoked**. This dynamic binding allows functions to operate on different objects depending on the call-site context.

As implemented in the source code analysis, the JavaScript engine follows four distinct invocation patterns to set the `this` binding, evaluated in strict order of precedence.

## The Four Rules of `this` Binding

The binding of `this` follows a clear precedence hierarchy. When multiple rules could apply, the engine uses the first matching pattern in the following order.

### 1. Constructor Invocation with `new`

The highest precedence rule applies when a function is invoked with the `new` keyword. This operation performs four steps:

1. Creates a brand-new object
2. Links the object's `[[Prototype]]` to the function's `prototype` property
3. Calls the function with the new object bound as `this`
4. If the function returns a non-object, the new object is returned instead

```javascript
function Person(name) {
  this.name = name;
}

const p = new Person('Ada');
// this → new object, p.name === 'Ada'

```

### 2. Explicit Binding with `call` and `apply`

The second precedence rule is **explicit binding**, where you directly specify the `this` context using `Function.prototype.call()` or `Function.prototype.apply()`. The first argument passed to either method becomes the `this` binding for that invocation.

```javascript
function setX(x) {
  this.x = x;
}

const other = { x: 0 };
setX.call(other, 20);
// this → other, other.x === 20

```

This pattern is commonly used for borrowing methods from other objects or fixing context for callbacks.

### 3. Implicit Binding with Method Calls

**Implicit binding** occurs when a function is accessed as a property of an object and invoked with dot notation (`obj.method()`). In this case, the object before the dot becomes the `this` binding.

```javascript
const point = {
  x: 0,
  init(x) {
    this.x = x;
  }
};

point.init(5);
// this → point, point.x === 5

```

This is the most common pattern for object-oriented method calls in JavaScript.

### 4. Default Binding

If none of the above rules apply, **default binding** takes effect. The behavior depends on **strict mode**:

- **Strict mode**: `this` is set to `undefined`
- **Non-strict mode**: `this` falls back to the global object (`globalThis`)

```javascript
function setX(x) {
  this.x = x;
}

setX(10);
// Non-strict → globalThis.x === 10
// Strict mode → TypeError (cannot set property 'x' of undefined)

```

This rule explains why standalone function references lose their context.

## Arrow Functions and Lexical `this`

Arrow functions (`=>`) behave differently from regular functions. According to **[objects-classes/ch5.md](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/objects-classes/ch5.md)** in the "An Arrow Points Somewhere" chapter, arrow functions **do not have their own `this` binding**.

Instead, they capture the `this` value of the **lexical surrounding scope** at the point where the arrow function is defined. Consequently, `call`, `apply`, and `new` have no effect on an arrow function's `this`.

```javascript
function Counter() {
  this.count = 0;
  // Arrow keeps the surrounding `this` (the Counter instance)
  this.inc = () => {
    this.count++;
  };
}

const c = new Counter();
const inc = c.inc;  // detached from object
inc();              // still works: c.count === 1

```

As noted in **[objects-classes/ch6.md](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/objects-classes/ch6.md)** in the "Lexical This" section, this behavior eliminates the need for the classic `var self = this` pattern when working with callbacks.

```javascript
// Arrow functions ignore explicit binding
const arrow = () => console.log(this);
arrow.call({ a: 1 });  // logs outer this, not { a: 1 }

```

## Summary

- The `this` keyword is a **runtime binding**, not an author-time reference, determined by how a function is invoked.
- Four precedence rules govern `this`: **constructor** (`new`), **explicit** (`call`/`apply`), **implicit** (method call), and **default** (global or `undefined` in strict mode).
- **Arrow functions** do not participate in these four rules; they inherit `this` lexically from their enclosing scope.
- Understanding these mechanisms, as detailed in **[objects-classes/ch4.md](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/objects-classes/ch4.md)** and related chapters, is essential for predictable object-oriented JavaScript.

## Frequently Asked Questions

### What determines the value of `this` in a JavaScript function?

The value of `this` is determined entirely by the **call-site**—how the function is invoked at runtime—not by where the function is declared. The JavaScript engine applies four precedence rules (constructor, explicit, implicit, default) to bind `this` to the appropriate object or value.

### Why does `this` become `undefined` in strict mode?

In **strict mode**, default binding sets `this` to `undefined` rather than the global object. This prevents accidental pollution of the global namespace when standalone functions are called without context, throwing a `TypeError` if you attempt to access properties on `undefined`.

### How do arrow functions handle `this` differently?

Arrow functions do not have their own `this` binding. Instead, they capture the `this` value from their **lexical surrounding scope** at definition time. This means `call`, `apply`, and `new` cannot change an arrow function's `this`, making them ideal for preserving context in callbacks.

### What is the difference between implicit and explicit binding?

**Implicit binding** occurs when you call a function as a method using dot notation (`obj.method()`), automatically setting `this` to the object before the dot. **Explicit binding** uses `call()` or `apply()` to manually specify the `this` context as the first argument, overriding implicit binding but yielding to constructor (`new`) binding.