Suggest an editImprove this articleRefine the answer for “Losing context”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`this`** in JS depends on how a function is called, not on where it is declared, so if a method is passed as a reference, it is no longer called "through the object", and `this` is lost. **Key point:** context can be preserved via `bind()`, an arrow function, saving `this` into a variable, `call`/`apply`, or binding the method in a class constructor.Shown above the full answer for quick recall.Answer (EN)Image## Why `this` gets lost `this` in JS depends **on how a function is called**, not on where it is declared. If you **pass a method as a reference**, it is no longer called "through the object", and `this` becomes `undefined` (or `window` in non-strict mode): ```javascript const user = { name: 'Tim', sayHi() { console.log(`Hello, I am ${this.name}`); } }; setTimeout(user.sayHi, 1000); // "Hello, I am undefined" ``` Why this happens: - `setTimeout` calls the function as `callback()`, not as `user.sayHi()`, so `this` loses its connection to the `user` object. --- ## Method 1 - `bind()` The `Function.prototype.bind()` method creates **a new function with a permanently bound context**. ```javascript setTimeout(user.sayHi.bind(user), 1000); // Hello, I am Tim ``` `bind` returns a new function in which `this` always points to `user`, regardless of how it is called. --- ## Method 2 - arrow functions Arrow functions **do not have their own** `this`, they **inherit it from the outer context** (lexically). ```javascript const user = { name: 'Tim', sayHiLater() { setTimeout(() => { console.log(`Hello, I am ${this.name}`); }, 1000); } }; user.sayHiLater(); // Hello, I am Tim ``` Here the arrow function "captured" `this` from `sayHiLater`. --- ## Method 3 - save `this` into a variable The classic "old" way, before arrow functions existed. ```javascript const user = { name: 'Tim', sayHiLater() { const self = this; setTimeout(function() { console.log(`Hello, I am ${self.name}`); }, 1000); } }; user.sayHiLater(); // Hello, I am Tim ``` Here `self` (or `that`) keeps a reference to the `user` context. --- ## Method 4 - call the function via `call` or `apply` You can manually set the context at call time. ```javascript function greet() { console.log(`Hello, ${this.name}`); } const user = { name: 'Tim' }; greet.call(user); // Hello, Tim greet.apply(user); // Hello, Tim ``` This is a *temporary binding*: it only works at the moment of the call. --- ## Method 5 - use a class (methods are called on an instance) Inside classes, `this` is usually not lost if you call the method through an instance: ```javascript class User { constructor(name) { this.name = name; } sayHi() { console.log(`Hello, ${this.name}`); } } const tim = new User('Tim'); tim.sayHi(); // Hello, Tim ``` But if the method is passed "detached", the context is lost again: ```javascript const fn = tim.sayHi; fn(); // undefined ``` To avoid this, you can bind the method in the constructor below. --- ## Method 6 - binding in the constructor (for classes and React) ```javascript class User { constructor(name) { this.name = name; this.sayHi = this.sayHi.bind(this); // permanently fix the context } sayHi() { console.log(`Hello, ${this.name}`); } } const tim = new User('Tim'); setTimeout(tim.sayHi, 1000); // Hello, I am Tim ``` This is especially useful in React classes (`this.handleClick = this.handleClick.bind(this)`). --- ## Method 7 - class fields A modern approach: methods declared as **arrow functions inside a class** automatically inherit `this`. ```javascript class User { name = 'Tim'; sayHi = () => { console.log(`Hello, ${this.name}`); }; } const tim = new User(); setTimeout(tim.sayHi, 1000); // Hello, Tim ``` This is ES2022 syntax (supported in all modern browsers). --- ## Method 8 - do not pass the method directly Sometimes it is simpler to just call the method **inside an anonymous wrapper**, so as not to lose `this`: ```javascript setTimeout(() => user.sayHi(), 1000); // Hello, I am Tim ``` Here `user.sayHi()` is called with the correct context. --- ## Summary | Method | What it does | Where it is often used | |---|---|---| | `.bind(this)` | Creates a function with a fixed context | Callbacks, React, timers | | **Arrow function** | Inherits `this` from the outer scope | setTimeout, async, promises | | `self = this` | Old way to save a reference | Legacy code, callbacks | | `call` **/** `apply` | Temporarily sets the context | One-off calls | | **Binding in a class** | Via `bind` in the `constructor` or an arrow function | React classes, OOP | | **Anonymous wrapper** | Calls the method within the context | Simple callbacks |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.