Compile Ready
Module 7 · The this Keyword

this in the Global Context

Intermediate9m read5m practice14m total
thisGlobal ObjectStrict ModeBinding Rules

Introduction

this is not a variable you declare. It is a runtime value supplied when a function is called. In the global context, its value depends heavily on where the code runs: classic browser scripts, ES modules, Node wrappers, and Web Workers differ.

For interviews, the safe mental model is: never guess from the text alone; ask how the function is invoked. Top-level this is mostly an environment detail, while function-call this follows binding rules.

Why This Matters

Many senior-looking bugs come from assuming this means the surrounding object or the current file. Interviewers use global-context questions to test whether you can separate JavaScript language semantics from host-environment behavior. In production, this matters when moving code between browser scripts, ES modules, bundlers, Web Workers, and Node.

Theory

The interview-safe framing

At the top level, this is host and source-type dependent:

ContextTypical top-level this
Classic browser scriptThe global object (window)
ES module in browser or Nodeundefined
Node CommonJS filemodule.exports, because Node wraps the file in a function
Web WorkerEnvironment-dependent enough that output puzzles should avoid printing it directly

The important lesson is not memorising every host. The important lesson is learning that top-level this is not the same interview problem as function-call this.

The four binding rules

When a regular function executes, JavaScript determines this from the call site using these rules:

  1. Default binding — plain call: fn(). In sloppy mode, this is substituted with the global object; in strict mode, this stays undefined.
  2. Implicit binding — property call: obj.fn(). this is obj.
  3. Explicit bindingfn.call(obj), fn.apply(obj), or fn.bind(obj). this is the supplied object, except arrows ignore it.
  4. new bindingnew Fn(). A fresh object becomes this inside the constructor.

Precedence

The rules have a useful precedence order:

new binding > explicit binding (call, apply, bind) > implicit binding > default binding.

A bound function called with new still uses the newly-created object as this. A method reference passed around without its object falls back to default binding unless it is bound or wrapped.

Strict mode changes default binding

Strict mode does not change implicit, explicit, or new binding. It changes the plain-call fallback. In strict mode, a plain call leaves this as undefined, which is safer because bugs fail loudly instead of silently writing to the global object.

Visual Diagrams

Call-site decision tree
How was the regular function called?
 |
 +-- new Fn(...)              -> this is the new object
 |
 +-- fn.call(obj, ...)        -> this is obj
 +-- fn.apply(obj, args)      -> this is obj
 +-- fn.bind(obj)(...)        -> this is obj
 |
 +-- obj.fn(...)              -> this is obj
 |
 +-- fn()                     -> default binding
                                strict: undefined
                                sloppy: global object

For regular functions, the call site matters more than where the function was written.

Code Examples

Top-level this is environment-specific

Use this as context, not as a portable rule. Modern code should prefer globalThis when it truly needs the global object.

Loading…

Strict mode makes default this fail loudly

A strict regular function called without an owner receives undefined as this.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1function inspectDefault() {
2 'use strict';
3 if (this === undefined) {
4 console.log('strict default');
5 }
6}
7
8function inspectExplicit() {
9 'use strict';
10 console.log(this.label);
11}
12
13inspectDefault();
14inspectExplicit.call({ label: 'explicit object' });

Predict the output #2

javascript
1function Person(name) {
2 this.name = name;
3}
4
5const ada = new Person('Ada');
6console.log(ada.name);
7console.log(ada instanceof Person);

Coding Exercises

Classify a call site's this binding

Easy

Implement classifyCallSite(expression) for the four expressions shown in the starter comments. Return default, implicit, explicit, or new. This is a reading exercise: focus on the syntax at the call site, not on where the function was defined.

Interview Questions

1What is `this` at the top level of JavaScript code?

It depends on the host and source type. In a classic browser script, top-level this is usually window. In an ES module, it is undefined. In Node CommonJS, the file is wrapped and top-level this is module.exports. For interviews, say that top-level this is environment-specific and then pivot to function-call binding rules.

Asked at:MicrosoftGoogleAmazon

Follow-ups

  • How is top-level `this` different in an ES module?
  • Why is `globalThis` safer when you need the global object?
2List the four `this` binding rules and their precedence.

The rules are default (fn()), implicit (obj.fn()), explicit (call, apply, bind), and new binding (new Fn()). Precedence is new > explicit > implicit > default. Strict mode affects only default binding: a plain call receives undefined instead of the global object.

Asked at:MetaNetflix

Quiz

1. Which statement about top-level `this` is the safest interview answer?

2. Which binding rule has the highest precedence for regular functions?

Summary

  • Top-level `this` is environment-specific; do not treat it as one portable rule.
  • Regular function `this` is determined by the call site.
  • The four rules are default, implicit, explicit, and `new` binding.
  • Precedence is `new` > explicit > implicit > default.
  • Strict mode changes default binding from global-object substitution to `undefined`.

Cheat Sheet

Top-level: classic script often global object; ES module undefined; Node CommonJS module.exports; workers vary.

Rules: fn() default, obj.fn() implicit, fn.call(obj) / apply / bind explicit, new Fn() new binding.

Precedence: new > explicit > implicit > default.

Strict mode: only default binding changes; plain-call this stays undefined.