Suggest an editImprove this articleRefine the answer for “Losing the this context”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**In JavaScript `this` is determined by how a function is called, not by where it is declared. As soon as a method is passed by reference (`setTimeout(user.sayHi)`), it is invoked as a plain function, and `this` becomes `undefined` in strict mode or the global object in sloppy mode. You pin the context like this: `bind(user)` returns a function with a permanently attached `this`; an arrow function inherits `this` lexically from the enclosing scope; an anonymous wrapper `() => user.sayHi()` calls the method through the object; `call` / `apply` set the context for a single call; inside classes you use `bind` in the constructor or a class field holding an arrow function.** ```javascript setTimeout(user.sayHi, 1000); // this is lost setTimeout(user.sayHi.bind(user), 1000); // context is fixed setTimeout(() => user.sayHi(), 1000); // called through the object ``` **Key point:** `this` is bound at call time, so either fix it in advance (`bind`, arrow class field) or always call the method through its object.Shown above the full answer for quick recall.Answer (EN)Image**Losing the context means calling an object's method without going through the object, so that `this` inside it no longer points to that object.** In JavaScript `this` is not baked into a function at declaration time: it is resolved on every call, based on how the function was invoked. ## Theory ### TL;DR - `this` is set by the call site: what stands to the left of the dot matters, not where the function was declared. - Passing a method by reference (`setTimeout(user.sayHi)`) breaks the link to the object. - `bind(obj)` returns a new function with a permanently fixed context. - Arrow functions have no `this` of their own and take it lexically from the enclosing scope. - `call` / `apply` set the context temporarily, only for the duration of one call. - In classes you fix the context with `bind` in the constructor or with a class field holding an arrow function. ### Quick example ```javascript const user = { name: 'Oleh', sayHi() { console.log(`Hi, I am ${this.name}`); } }; user.sayHi(); // "Hi, I am Oleh" setTimeout(user.sayHi, 1000); // "Hi, I am undefined" ``` ### Why `this` gets lost `setTimeout` receives only a reference to the function and invokes it as `callback()`, not as `user.sayHi()`. There is no object to the left of the dot any more, so the binding to `user` disappears: - in strict mode (and ES modules are always strict) `this` is `undefined`, and reading `this.name` throws a `TypeError`; - in sloppy mode `this` is substituted with the global object (`window` in the browser), and `this.name` quietly returns `undefined`. The same happens with any detached method: event handlers, `array.map(obj.method)`, storing a method in a variable. ### Pinning the context: `bind`, `call` and `apply` `Function.prototype.bind()` creates a **new** function with a hard-wired context, no matter how it is called later: ```javascript setTimeout(user.sayHi.bind(user), 1000); // "Hi, I am Oleh" ``` `call` and `apply`, by contrast, do not create a new function: they invoke the existing one with the given context right now. That is a temporary binding, valid only for this call: ```javascript function greet() { console.log(`Hi, ${this.name}`); } const user = { name: 'Oleh' }; greet.call(user); // "Hi, Oleh" greet.apply(user); // "Hi, Oleh" ``` The only difference between them is argument passing: `call` takes them as a list, `apply` as an array. ### Arrow functions, the `self` variable and wrappers An arrow function has no `this` of its own: it takes it from the scope where it was created. Inside a method it therefore closes over the correct context: ```javascript const user = { name: 'Oleh', sayHiLater() { setTimeout(() => { console.log(`Hi, I am ${this.name}`); }, 1000); } }; user.sayHiLater(); // "Hi, I am Oleh" ``` Before arrow functions existed, the same effect was achieved by saving the context into a `self` or `that` variable: ```javascript const user = { name: 'Oleh', sayHiLater() { const self = this; setTimeout(function() { console.log(`Hi, I am ${self.name}`); }, 1000); } }; user.sayHiLater(); // "Hi, I am Oleh" ``` The simplest option, when you control the place where the callback is passed, is not to pass the method directly at all but to call it inside an anonymous wrapper: ```javascript setTimeout(() => user.sayHi(), 1000); // "Hi, I am Oleh" ``` Here `user.sayHi()` is called through the object, so the context is correct. ### Context inside classes In a class `this` usually survives, as long as the method is called through an instance: ```javascript class User { constructor(name) { this.name = name; } sayHi() { console.log(`Hi, ${this.name}`); } } const oleh = new User('Oleh'); oleh.sayHi(); // "Hi, Oleh" ``` But detach the method from the instance and the context is gone again (class bodies always run in strict mode, so this throws): ```javascript const fn = oleh.sayHi; fn(); // TypeError: Cannot read properties of undefined ``` The classic fix is binding in the constructor: ```javascript class User { constructor(name) { this.name = name; this.sayHi = this.sayHi.bind(this); // fix the context once and for all } sayHi() { console.log(`Hi, ${this.name}`); } } const oleh = new User('Oleh'); setTimeout(oleh.sayHi, 1000); // "Hi, Oleh" ``` This is exactly how React class components were written for years: `this.handleClick = this.handleClick.bind(this)`. The more modern option is class fields (ES2022): a method declared as an arrow function automatically inherits the instance's `this`: ```javascript class User { name = 'Oleh'; sayHi = () => { console.log(`Hi, ${this.name}`); }; } const oleh = new User(); setTimeout(oleh.sayHi, 1000); // "Hi, Oleh" ``` Class field syntax is supported by every modern browser. The price is that such a function is created per instance instead of living once on the prototype. ### Summary table | Approach | What it does | Where it is used | | --- | --- | --- | | `.bind(this)` | Creates a new function with a fixed context | Callbacks, React, timers | | Arrow function | Inherits `this` from the enclosing scope | `setTimeout`, async, promises | | `const self = this` | The old way to keep a reference to the context | Legacy code, callbacks | | `call` / `apply` | Sets the context temporarily, for one call | One-off invocations | | Binding in a class | `bind` in the constructor or an arrow class field | React classes, OOP | | Anonymous wrapper | Calls the method through the object | Simple callbacks | ### Common mistakes - **Assuming `this` depends on where the function is declared.** It depends only on how it is called; the same function can have a different `this` on every call. - **Calling `bind` inside render or inside a handler.** `bind` returns a **new** function every time, so reference comparison breaks and `removeEventListener` cannot detach the listener. Bind once, in the constructor or in a class field. - **Trying to "reassign" `this` on an arrow function.** `arrow.call(obj)` and `arrow.bind(obj)` have no effect: an arrow has no `this` of its own. - **Using an arrow as an object literal method.** `{ name: 'Oleh', sayHi: () => this.name }` takes `this` from the enclosing scope, not from the object. - **Forgetting that the failure is silent.** In sloppy mode nothing throws: you simply see `undefined` instead of the value.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.