Skip to content

Intermediate · Scope, this, prototypes and classes · topic 22 of 61 · 30 min

How this works

Explanation

this is a special value inside a function that usually means "the object this function was called on". It is decided by HOW the function is called, not where it is written: obj.method() sets this to obj, a plain call gives undefined in strict mode, new sets it to the new object, and call, apply and bind set it yourself. Arrow functions do not have their own this.

Why this exists

One method should work for many objects. A greet method on every user should say that user's name. this lets the method refer to "whichever object I was called on" without knowing its name in advance.

javascript
function greet() {
  return `Hi, I am ${this.name}`;
}
const asha = { name: 'Asha', greet };
const ravi = { name: 'Ravi', greet };
console.log(asha.greet()); // Hi, I am Asha
console.log(ravi.greet()); // Hi, I am Ravi

Rule 1: method call → the object before the dot

When you call obj.method(), this inside method is obj. Only the call matters: the same function gives a different this when called on another object.

Rule 2: plain call → undefined (strict mode)

Calling a function on its own, f(), gives this = undefined in strict mode (modules and classes are always strict). In old sloppy scripts it is the global object (window in browsers), which hides bugs.

The lost-this bug

javascript
'use strict';
const counter = {
  count: 0,
  inc() { this.count++; return this.count; },
};
const inc = counter.inc;   // just the function, the object is lost
// inc();                   // TypeError: Cannot read properties of undefined
setTimeout(counter.inc, 0); // same bug: called later as a plain function

Passing a method as a callback passes only the function. When it is later called without an object before a dot, this is lost.

Rule 3: call, apply and bind set this yourself

javascript
function intro(city, state) {
  return `${this.name} from ${city}, ${state}`;
}
const user = { name: 'Meena' };
console.log(intro.call(user, 'Kochi', 'Kerala'));     // arguments one by one
console.log(intro.apply(user, ['Kochi', 'Kerala']));  // arguments as an array
const bound = intro.bind(user);                       // a NEW function with this fixed
console.log(bound('Kochi', 'Kerala'));
All three print Meena from Kochi, Kerala.

Rule 4: new → the brand-new object

With new (constructors and classes, next topics), this is the new object being built.

Arrow functions take this from outside

An arrow function has no this of its own. Inside it, this means whatever this was in the code around it when the arrow was created. That makes arrows perfect for callbacks inside methods, and wrong as methods themselves.

javascript
const timer = {
  seconds: 0,
  start() {
    // arrow: this is still timer
    const tick = () => { this.seconds++; };
    tick(); tick();
    return this.seconds;
  },
};
console.log(timer.start()); // 2
How the function is calledthis is
obj.method()obj
f() (strict mode)undefined
f.call(x) / f.apply(x) / f.bind(x)()x
new F()the new object
arrow functionthis of the surrounding code
Careful: Fix lost this in callbacks by wrapping in an arrow, setTimeout(() => counter.inc(), 0), or by binding, setTimeout(counter.inc.bind(counter), 0). Do not fix it by making the method itself an arrow on an object literal; then this is never the object.
Think of it like this: this is like the word "my" in a sentence. "Pass me my bag" means different bags depending on who says it. The sentence (the function) is the same; the speaker (how it is called) decides whose bag.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

How this works · 1/6

this

In this lesson you will learn the rules that decide what this means.

Prefer a video by a teacher? Find free videos on “javascript this keyword call apply bind arrow functions” on YouTube ↗

In real life: A payment button that forgot its order

A checkout page passed order.pay as a click handler. When clicked, pay ran as a plain function, this was undefined, and the payment crashed with "Cannot read properties of undefined (reading 'amount')". Wrapping it in an arrow fixed it.

javascript
const order = { amount: 799, pay() { return `Paying ₹${this.amount}`; } };
const handlerBroken = order.pay;
const handlerFixed = () => order.pay();
console.log(handlerFixed()); // Paying ₹799

Practice (0/3 done)

Task 1 · Code · Javascript

Complete the method describe so it returns "<name> costs Rs <price>" using this. Example: "Pen costs Rs 20".

Task 2 · Code · Javascript

runLater(fn) calls fn as a plain function. getCounterCallback(counter) must return a function that, when called plainly, increases counter.count by 1 and returns the new count. Use bind or an arrow.

Task 3 · Code · Javascript

Write introduceAll(people, fn) that calls fn once for each person with this set to that person (use call), and returns the array of results.

Quick quiz

Question 1

1.const o = { n: 1, get() { return this.n; } }; What is o.get()?

Question 2

2.In strict mode, function f() { return this; } What is f()?

Question 3

3.What does bind return?

Question 4

4.const o = { n: 5, get: () => this.n }; In a module, what is o.get()?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

const o = { n: 1, get() { return this.n; } }; What is o.get()?

Answer: 1

Called as a method, this is o.

In strict mode, function f() { return this; } What is f()?

Answer: undefined

A plain call in strict mode gives this = undefined.

What does bind return?

Answer: A new function with this fixed

bind does not call the function; it returns a bound copy.

const o = { n: 5, get: () => this.n }; In a module, what is o.get()?

Answer: undefined, or an error

The arrow takes this from the module scope, where this is undefined, so reading .n throws or gives undefined; it is never o.

Why is an arrow function a bad choice for an object method that uses this?Related

Answer: Arrows have no own this

An arrow uses the this of the surrounding code, not the object.

From Arrow functions

A variable is declared with const inside a function. Where can it be used?Related

Answer: Only inside that function

let and const are block-scoped: they live only inside their { }.

From Functions

What does Object.keys({ a: 1, b: 2 }) return?Related

Answer: ['a', 'b']

Object.keys gives the property names.

From Objects: keys and values

const list = [1]; list.push(2); What happens?Related

Answer: list becomes [1, 2]

const stops reassignment of the name, not changes inside the array.

From Variables: let, const and var

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Scope, this, prototypes and classes” before its exam: Prototypes and the prototype chain, Classes, Inheritance and composition.
  2. Module 5 exam: Scope, this, prototypes and classes · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Modules, errors, JSON and dates. 61 topics left in the course before the final exam.

← Previous: Hoisting and the temporal dead zone