JavaScript: this Keyword and Context
Learn what 'this' refers to in different situations and how to control it with call, apply, and bind.
What is this?
this is a special keyword that refers to an object. Which object it points to depends entirely on how and where the function containing it is called, not where the function is defined (except for arrow functions).
this
this is resolved at call time, not at definition time, for regular functions.
- The value of
thisis set each time a function is invoked - Different call patterns produce different
thisvalues - Arrow functions are the exception: they capture
thisfrom the surrounding scope at definition time - Understanding
thisis key to working with objects, classes, and callbacks correctly
this Depends on the Call
The same function logs different values for this depending on how it is called.
Press Run to execute the code and see output here.
Global Context
At the top level of a script (outside any function), this refers to the global object, window in browsers,global in Node.js.
Global this
At the top level, this is the global object, the container for all global variables.
- In a browser:
this === windowat the top level - In Node.js: top-level
thisis an empty module object, notglobal - In strict mode (
"use strict"),thisinside a plain function call isundefined, not the global object
Global Context
At the top level and in plain function calls, this points to the global object.
Press Run to execute the code and see output here.
Function Context
When a regular function is called as a plain function (not as a method), this is the global object in non-strict mode, or undefined in strict mode.
Function Context
Plain function calls do not set a meaningful this, rely on explicit binding instead.
- Non-strict:
thisdefaults to the global object - Strict mode (
"use strict"):thisisundefined, accessing properties on it throws - ES modules run in strict mode automatically, so
thisinside module functions isundefined
Function Context in Strict vs Loose Mode
Strict mode makes this undefined in plain function calls, exposing accidental usage.
Press Run to execute the code and see output here.
Method Context
When a function is called as a method of an object, using dot notation, this is set to the object before the dot.
Method Context
The object to the left of the dot at call time becomes this.
- It is the call site that matters, not where the method is defined
- The same function can serve as a method on different objects, getting a different
thiseach time - Chained methods like
obj.a.b()setthistoobj.a(the object immediately before the call)
Method Context
this is determined by the object the method is called on, not where it was defined.
Press Run to execute the code and see output here.
Event Handler Context
In a DOM event handler, this refers to the element that the listener is attached to, when using a regular function.
Event Handler this
The browser sets this to the DOM element that fired the event when using regular function handlers.
- A regular function handler:
thisis the element (event.currentTarget) - An arrow function handler:
thisis inherited from the surrounding scope, NOT the element - Use a regular function when you need to reference the element via
thisinside the handler
Event Handler Context
Use a regular function when you need this to be the clicked element.
Press Run to execute the code and see output here.
Arrow Functions and this
Arrow functions do not have their own this. They capture this from the enclosing lexical scope at the time they are defined, and it never changes.
Arrow Functions and this
Arrow functions inherit this from where they are written, a major reason to prefer them in callbacks.
- Cannot be bound, called, or applied with a different
this - Perfect for callbacks inside methods where you want to keep the method's
this - Do NOT use arrow functions as object methods if you need
thisto be the object
Arrow Function Preserving this
The arrow inside setInterval captures this from start(), which is timer.
Press Run to execute the code and see output here.
Explicit Binding: call()
call() invokes a function immediately with a specified this value and arguments passed one by one.
call()
call() lets you borrow a method and run it with a different this on the spot.
- Syntax:
fn.call(thisArg, arg1, arg2, ...) - Executes immediately, does not return a new function
- Useful for borrowing methods from one object and using them on another
call() Example
Borrow introduce and run it with different objects and arguments.
Press Run to execute the code and see output here.
Explicit Binding: apply()
apply() works exactly like call(), but accepts arguments as an array instead of individually.
apply()
Use apply() when your arguments are already in an array or array-like object.
- Syntax:
fn.apply(thisArg, [arg1, arg2, ...]) - Executes immediately, just like
call() - Classic use:
Math.max.apply(null, numbersArray)to spread an array into Math.max
apply() Example
Pass an existing array directly as arguments, no need to unpack manually.
Press Run to execute the code and see output here.
Explicit Binding: bind()
bind() returns a new function withthis permanently set to the given value. The new function can be called later.
bind()
bind() creates a reusable version of a function with a fixed this.
- Syntax:
const bound = fn.bind(thisArg, ...partialArgs) - Does NOT execute immediately, returns a new function
- Calling
bind()a second time on an already-bound function has no effect - Ideal for passing methods as callbacks without losing their object context
bind() Example
Lock this for a delayed callback, and use partial application to pre-fill arguments.
Press Run to execute the code and see output here.
call vs apply vs bind
All three methods let you set this explicitly, but they differ in when and how the function runs.
| Method | Executes | Arguments | Returns |
|---|---|---|---|
call(ctx, a, b) | Immediately | Listed individually | Function result |
apply(ctx, [a, b]) | Immediately | Single array | Function result |
bind(ctx, a, b) | Later (you call it) | Listed individually (partial ok) | New bound function |
Lost Context and Solutions
Context is "lost" when a method is detached from its object before being called, most commonly when passing a method as a callback. The function then runs without a receiver, and this reverts to the global object or undefined.
Lost Context
Extracting a method from its object breaks the this binding.
- Common cause: passing
obj.methodas a callback (e.g. to setTimeout or an array method) - Fix 1: use
.bind(obj)when passing the callback - Fix 2: wrap in an arrow function:
() => obj.method() - Fix 3: store
const self = thisbefore an old-style callback (legacy pattern)
Lost Context and Fixes
Detaching increment breaks this, bind or an arrow wrapper restores it.
Press Run to execute the code and see output here.
Knowledge Check
1. What does 'this' refer to inside a regular function called in non-strict mode in a browser?
2. What does 'this' refer to inside a method called on an object?
3. How do arrow functions handle 'this'?
4. What is the difference between call() and apply()?
5. What does bind() return?
6. Why is 'this' lost when a method is passed as a callback?
7. Which is the best fix to preserve 'this' when passing a method as a callback?