LESSON 19 · INTERMEDIATE4 min read

The Four Rules of this: Default, Implicit, Explicit & new

Master the most misunderstood keyword in JavaScript. Learn the four deterministic rules that govern 'this' binding at call time.

ES2024 / Node.js 20+Free to readModule 5 of 10
YOUR NEXT SMALL WINS

By the end, you’ll be able to…

  • Identify the four rules of 'this' binding: Default, Implicit, Explicit, and 'new'.
  • Control execution context using call(), apply(), and bind().
  • Explain how arrow functions bypass these four rules via lexical inheritance.

01The Golden Rule of 'this'

The keyword this in JavaScript is legendary for generating confusion. Many developers mistakenly believe this refers to the function itself, or to the function's lexical scope. Neither is true.

The golden rule of this is simple: this is NOT author-time binding; this is CALL-SITE runtime binding. What this refers to is determined entirely by HOW a function is called, not where it was declared (with the sole exception of arrow functions, which borrow this lexically).

The value of the 'this' keyword is never fixed by the function's declaration (with the singular exception of arrow functions); it is determined dynamically by the Call-Site: the exact syntactic form used to invoke the function at runtime.

To master 'this', you only need to apply four precedence rules in order: 1) New Binding: was the function called with new? If so, this is the newly constructed object. 2) Explicit Binding: was it called with call, apply, or bind? If so, this is the explicitly specified context. 3) Implicit Binding: was it called as an object method (obj.fn())? If so, this is the context object. 4) Default Binding: if none of the above apply, this is undefined in strict mode (or window/global in sloppy mode).

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

02The Four Deterministic Rules

To determine what this references at any call site, evaluate these four rules in strict order of precedence: 1. new Binding: Was the function invoked with new? If so, this is the newly constructed object. 2. Explicit Binding: Was the function invoked with call(), apply(), or bind()? If so, this is the explicitly specified object. 3. Implicit Binding: Was the function invoked with a context object (obj.method())? If so, this is that context object. 4. Default Binding: If none of the above apply (a standalone function call like fn()), this is the global object (window/global), or undefined if executing in strict mode ('use strict').

Memorizing this 4-step precedence order demystifies every single this binding scenario you will ever encounter in JavaScript.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

03Losing Implicit Binding: The Detached Method Trap

One of the most frequent production bugs occurs when an implicit method reference is passed as a callback: const handler = user.greet; setTimeout(handler, 1000).

When setTimeout executes handler, it invokes it as a standalone function call! The implicit binding to user is completely lost, causing this to fall back to Default Binding (undefined or window). To fix this, you must explicitly hard-bind the function using .bind(user) or wrap it in an arrow function.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

04Why This Matters in Production

In enterprise web applications, UI event handlers, class method callbacks, and asynchronous promise handlers routinely crash with TypeError: Cannot read properties of undefined (reading 'setState') when developers pass detached methods without binding.

By knowing the 4 rules and the precedence order (new > explicit > implicit > default), you can instantly diagnose and resolve broken context bugs, create robust bound handlers, and leverage explicit binding for clean functional delegation.

LET IT CLICK

The ideas worth keeping.

  • 'this' is determined at call time by how the function is invoked, not where it was declared.
  • Precedence order: new Binding > Explicit (call/apply/bind) > Implicit (obj.fn) > Default (undefined in strict mode).
  • Use .bind(this) or arrow functions to prevent detached methods from losing context in callbacks.
TURN UNDERSTANDING INTO SOMETHING YOU CAN DO

Make it yours.

Type and test your code right here in the interactive workspace. Run your solution, check the output, and compare with the worked guide when ready.

01

Exercise 1: Hard-Binding Context Helper

Write a function bindContext(fn, context) that replicates the core behavior of Function.prototype.bind using a closure and apply().

your_turn_1.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.jsJavaScript
function bindContext(fn, context) {  return function(...args) {    return fn.apply(context, args);  };}

Returning a closure that invokes fn.apply(context, args) guarantees that 'this' is locked to the specified context.

02

Exercise 2: Fixing Detached Event Handler

Fix this class component handler so that passing this.handleClick as an event listener preserves 'this': class Button { click() { return this.label; } }

your_turn_2.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.jsJavaScript
class Button {  constructor(label) {    this.label = label;    this.handleClick = this.click.bind(this);  }  click() {    return this.label;  }}

Binding the method in the constructor guarantees that 'this' remains permanently bound to the instance, even when passed as a detached callback.

A SMALL QUESTION. A USEFUL NEXT STEP.

What stayed with you?

Check the ideas while they’re fresh. Your answers stay in this page and feedback appears as you go.

A LITTLE ACTIVE RECALL0 / 3 answered
01Which binding rule takes the HIGHEST precedence when determining the value of 'this'?
02What is 'this' in a standalone function call in strict mode ('use strict')?
03What happens when you pass an object method directly as a callback to setTimeout(obj.method, 100)?
⚡CODING CHALLENGE
🔒Required to Mark Lesson Complete

Exercise 1: Hard-Binding Context Helper

Write a function bindContext(fn, context) that replicates the core behavior of Function.prototype.bind using a closure and apply().

EXPECTED OUTPUT
[Process exited with code 0 - No output]
main.jsJavaScript
Ctrl + ↵
Execution Console
Click "Run & Verify" (or press Ctrl + Enter) to test your code against the challenge.

Keep exploring.

The official references behind this lesson, when you want a second angle or the full details.

One lesson closer.

Reading is a start. Trying it yourself makes the connection.

Solve the hands-on coding challenge in the knowledge section to verify your code and unlock lesson completion.