JavaScriptthis KeywordFunction BindingExecution Context

The this Keyword, Demystified

14, July 2026 - By Admin

The this keyword in JavaScript - Ahmed Hamada
T

The `this` keyword is one of the most misunderstood parts of JavaScript. Its value isn't fixed -- it depends entirely on how a function is called. This post breaks down the binding rules and the special case of arrow functions.

Few features of JavaScript trip up developers as often as the `this` keyword. Unlike languages with static, lexically-scoped `this`, JavaScript determines the value of `this` at **call time** based on how a function is invoked, not where it's defined. This dynamic behavior is powerful once understood, but it's also a common source of bugs.

In this article, we'll walk through the rules that govern `this` binding -- default, implicit, explicit, and `new` -- along with how arrow functions sidestep these rules entirely by inheriting `this` lexically. We'll also cover the pitfalls developers run into most often, like losing `this` inside callbacks and class methods.

The value of `this` is not about where a function is written, it's about how a function is called.- JavaScript Guru
Default Binding

When a function is invoked on its own -- without being attached to an object, without `call`/`apply`/`bind`, and without `new` -- the **default binding** rule applies. In non-strict mode, `this` falls back to the global object (`window` in browsers, `global` in Node.js). In `'use strict'` mode (which ES modules and class bodies use automatically), `this` is `undefined` instead, which helps catch mistakes early.

Implicit Binding: Method Calls

**Implicit binding** kicks in when a function is called as a property of an object, using dot notation: `obj.method()`. In this case, `this` inside the function refers to the object the method was called on -- whichever object appears immediately to the left of the dot at the call site.

It's important to remember that implicit binding depends on the **call site**, not where the function was defined. If you extract a method and call it separately, it loses its implicit binding, as shown in the pitfalls section below.

new Binding in Constructor Functions

When a function is invoked with the `new` keyword, JavaScript performs several steps automatically: it creates a brand-new empty object, links that object's internal prototype to the constructor's `prototype` property, executes the function with `this` bound to the new object, and returns the new object (unless the function explicitly returns another object).

This is the highest-precedence binding rule -- `new` always wins over implicit or default binding at the call site.

Arrow Functions and Lexical this

Arrow functions do not have their own `this`. Instead, they capture `this` **lexically** from the enclosing scope at the time they are defined, just like they do with variables. None of the rules above apply to arrow functions -- `call`, `apply`, and `bind` cannot change an arrow function's `this`, and calling an arrow function with `new` throws a `TypeError`.

This makes arrow functions ideal for callbacks that need access to the surrounding `this`, such as event handlers or asynchronous code inside a method, since they simply reuse whatever `this` was in scope where they were created.

Common Pitfalls: Losing this in Callbacks and Class Methods

A frequent source of bugs is passing a regular function as a callback and expecting it to retain the `this` of the object it came from. Because `this` is determined by the call site, not the definition site, a callback invoked by `setTimeout`, an event listener, or an array method loses its original `this` unless it's an arrow function or has been explicitly bound.

The same issue appears with class methods: extracting a method from an instance (for example, passing `this.handleClick` directly as an `onClick` prop) detaches it from the instance, so `this` inside the method is no longer the instance when it's later called. Binding the method in the constructor, using `bind()` at the call site, or defining the method as an arrow function class field are the three common fixes.

The Rules of this Binding, in Precedence Order:
  • **new Binding:** When a function is called with `new`, `this` refers to the newly created instance -- highest precedence.
  • **Explicit Binding:** `call`, `apply`, and `bind` let you set `this` directly, overriding implicit and default binding.
  • **Implicit Binding:** When a function is called as a method (`obj.method()`), `this` refers to the object before the dot.
  • **Default Binding:** When a function is called standalone, `this` is `undefined` in strict mode or the global object otherwise.
Controlling this Explicitly:
  1. 1 - Use `call` to invoke a function immediately with a specific `this` and individual arguments:

  2. 2 - Use `apply` the same way, but pass arguments as an array:

  3. 3 - Use `bind` to create a new function with `this` permanently bound, without invoking it immediately:

JavaScriptthis KeywordFunction BindingExecution Context
Ahmed Hamada profile picture
Ahmed Hamada

A JavaScript enthusiast who loves exploring different patterns and techniques to improve code efficiency.

React - Ahmed Hamada
TypeScript - Ahmed Hamada
Node.js - Ahmed Hamada
Next.js - Ahmed Hamada
Ahmed Hamada