By the end of this lesson, you will be able to explain how JavaScript chooses the value of this and use it safely in object methods and callbacks.
What it is
this is a keyword that refers to the object currently associated with a function call. In a normal method, it is the object before the dot: obj.method() makes this equal to obj. In a constructor or class method called on an instance, it refers to that instance. It is not a fixed property of the function; it is chosen when the function is called. Related terms include implicit binding, explicit binding, default binding, and lexical this in arrow functions.
Why it matters
- It lets methods read and update the object they belong to.
- It helps write reusable object-oriented code without passing the object manually.
- It explains common bugs when methods are detached or used as callbacks.
- It guides when to use arrow functions,
bind(),call(), orapply(). - It is central to prototypes, classes, and many DOM event patterns.
Syntax or steps
- Define a method on an object using shorthand:
name() { ... }. - Call it as a method:
obj.name(). - Inside the method, use
thisto access object properties. - If the function may be detached, bind it:
obj.name.bind(obj). - For callbacks inside methods, prefer an arrow function so it inherits the method's
this. - Use
call()orapply()when you need one-time explicit binding.
Example
const user = {
name: "Ada",
greet() {
return "Hello, " + this.name;
},
announce() {
console.log(this.greet());
}
};
user.announce();
const detached = user.greet.bind(user);
console.log(detached());
const timerUser = {
name: "Grace",
start() {
setTimeout(() => {
console.log("Timer says: " + this.name);
}, 0);
}
};
timerUser.start();
Part by part: user.announce() calls greet() as a method, so this is user. bind(user) creates a new function whose this is fixed to user, even if called alone. The arrow function inside setTimeout does not create its own this; it inherits this from start(), which is timerUser. Expected output: Hello, Ada, Hello, Ada, Timer says: Grace.
Common mistakes
- Losing the object:
const fn = obj.method; fn();changesthis. Fix: callobj.method()or usebind(). - Using a regular callback:
setTimeout(function() { this.name; }, 0)does not keep the method'sthis. Fix: use an arrow function. - Assuming arrow functions have their own
this: they use lexicalthis, so they are not good replacements for object methods that need dynamic binding. - Forgetting strict mode: in strict mode, default binding can make
thisundefinedinstead of the global object.
When to use it
| Pattern | How this is chosen | Use when |
|---|---|---|
obj.method() | The object before the dot | Normal object methods |
arrow() inside a method | Inherited from surrounding method | Callbacks like setTimeout |
method.bind(obj) | Explicitly fixed to obj | Passing a method as a callback |
method.call(obj) | Explicitly set for one call | Invoking a function with a chosen object once |
Practice
Guided exercise: Create an object called book with a title property and a describe() method that returns "Title: " + this.title. Call book.describe(). Expected output: Title: ....
Challenge: Fix this code so it logs Desk lamp is on:
const lamp = {
name: "Desk lamp",
turnOn() {
setTimeout(function() {
console.log(this.name + " is on");
}, 0);
}
};
lamp.turnOn();
Solution hint: replace function() { ... } with () => { ... }, or use bind(this).
Quick check
Question: In obj.method(), what is this inside method?
Answer: It is obj, because the method was called on that object.
Summary
this is about how a function is called, not where it is written. Use method calls for normal object behavior, arrow functions for callbacks that should inherit the method's context, and explicit binding when a function must keep a chosen object.