Suggest an editImprove this articleRefine the answer for “The this keyword in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`this`** is a reference to the object invoking the current function, resolved at call time. Regular functions get `this` from the call site. Arrow functions inherit it from the enclosing scope at creation. `call`, `apply`, and `bind` set `this` explicitly. ```javascript const obj = { name: 'Alice', fn() { return this.name; } }; obj.fn(); // "Alice" const f = obj.fn; f(); // undefined (strict mode) ``` **Key rule:** who calls the function determines `this`, unless it is an arrow.Shown above the full answer for quick recall.Answer (EN)Image**`this`** is a reference to the object that is currently invoking the function. The value is determined at call time, not at definition time. ## Theory ### TL;DR - `this` is like a "who's calling?" display: it shows the caller, not the function itself - Regular functions get `this` from the call site; arrow functions lock it from the scope where they were written - `obj.method()` sets `this` to `obj`; passing that method as a callback loses the binding - Regular functions for object methods, arrows for callbacks and nested functions - `call`, `apply`, and `bind` let you set `this` explicitly ### Quick example ```javascript const obj = { name: 'Alice', regular: function() { console.log(this.name); }, // this = obj arrow: () => console.log(this.name) // this = outer scope }; obj.regular(); // "Alice" obj.arrow(); // undefined (strict mode) ``` Two functions, same object, opposite results. The call `obj.regular()` binds `this` to `obj`. The arrow function ignores that completely. It captured `this` from the surrounding scope at the moment it was defined, and nothing changes that. ### Key difference Regular functions resolve `this` at runtime based on how they are invoked. `obj.method()` means `this` is `obj`; calling `fn()` standalone means `this` is the global object, or `undefined` in strict mode. Arrow functions skip this resolution entirely. They lock `this` to whatever the enclosing scope held at creation time. Passing `call`, `apply`, or `bind` to an arrow function has zero effect on its `this`. ### When to use - **Object method that reads or writes instance data**: regular function - **Callback for `setTimeout`, `forEach`, or event listeners**: arrow, it preserves outer `this` - **Constructor with `new`**: regular function only. Arrows throw `TypeError: not a constructor` - **Class event handler**: arrow class field (`handleClick = () => {}`) removes the need for manual `bind` in the constructor - **Standalone utility with no object context**: arrow, no risk of accidentally touching global `this` ### How `this` gets resolved JavaScript engines attach an execution context to every function call. For regular functions, the engine checks the call site: `obj.fn()` sets `this` to `obj`; `fn()` alone falls back to the global object (or `undefined` in strict mode). `bind()` creates a new function with a hardcoded `this` that overrides any call site. Arrow functions do not participate in this mechanism at all. They capture `this` from the parent scope's activation record at creation time, so no invocation can alter it. One environment detail worth knowing: in ESM modules, the top-level `this` is always `undefined`. In CommonJS it points to `module.exports`. That difference surfaces when debugging Node.js utility files. ### Common mistakes **Arrow function used as an object method:** ```javascript const user = { name: 'Bob', greet: () => console.log(this.name) // wrong: arrow has no binding to user }; user.greet(); // undefined ``` Arrows do not have access to the object they sit inside. Use a regular function for any method that needs to read properties off its object. **Losing `this` in a callback:** ```javascript const logger = { prefix: '[INFO]', log: function() { console.log(this.prefix); // undefined, this = global inside setTimeout } }; setTimeout(logger.log, 0); // detached from logger setTimeout(() => logger.log(), 0); // works: arrow wrapper calls log as a method ``` Passing `logger.log` to `setTimeout` extracts the function from its object. The binding is gone. The arrow wrapper fixes this by calling the method directly on the object rather than passing a bare reference. This is the mistake I see most often in code reviews, including in production Express codebases where a method reference gets handed off to a queue and fails without an obvious error. **Unbound event handler:** ```javascript function Counter() { this.count = 0; document.querySelector('button').addEventListener('click', function() { this.count++; // this = button element, not the Counter instance }); } ``` Fix: use an arrow function or call `.bind(this)` when attaching the listener. **Calling `new` on an arrow:** ```javascript const Ctor = () => {}; new Ctor(); // TypeError: Ctor is not a constructor ``` Arrows have no `[[Construct]]` internal slot. Only regular functions can be used with `new`. ### Real-world usage - **React class components**: `this.setState()` and `this.props` depend on `this` pointing to the component instance. Arrow class fields (`handleClick = () => {}`) replaced manual `bind` calls in constructors and are still common in legacy codebases - **Express error handler classes**: methods need `bind` or arrow class fields to keep `this` on the instance when Express calls them - **Node.js Transform streams**: `this.push(chunk)` inside `_transform` works because Node calls it as a method on the stream object - **Lodash**: `_.bind(fn, context)` and `_.bindAll(obj, methods)` exist specifically for fixing `this` in callback-heavy code ### Follow-up questions **Q:** What is `this` inside `setTimeout(fn, 0)`? **A:** The global object, or `undefined` in strict mode. `setTimeout` calls the function without an object context, so the binding is lost. **Q:** What is the difference between `call`, `apply`, and `bind`? **A:** All three set `this` explicitly. `call` and `apply` invoke the function immediately: `call` takes individual arguments, `apply` takes an array. `bind` returns a new function with `this` permanently set, without invoking it. **Q:** What is `this` at the top level of an ES module? **A:** Always `undefined`. In CommonJS modules it is `module.exports`. **Q:** How does `new` affect `this`? **A:** `new` creates an empty object, sets `this` to it inside the constructor, and returns that object unless the constructor explicitly returns a different object. **Q:** Can you override `this` in an arrow function using `call` or `bind`? **A:** No. Arrow functions ignore any `this` passed via `call`, `apply`, or `bind`. The lexical binding is permanent from the moment the function is created. **Q:** (Senior) How does V8 handle `this` in optimized code? **A:** V8 uses inline caches to track the type of `this` at each call site. If the type stays consistent across calls (monomorphic), TurboFan can optimize aggressively. If the type varies (polymorphic), V8 deoptimizes. This is one reason consistent object shapes and strict mode improve runtime performance. ## Examples ### Method call vs detached call ```javascript const car = { speed: 60, accelerate: function() { this.speed += 10; console.log(this.speed); } }; car.accelerate(); // 70, this = car const fn = car.accelerate; fn(); // NaN in strict mode (undefined + 10) or modifies global speed ``` Assigning a method to a variable detaches it from the object. The function body is identical in both cases. Only the call site differs, and that is what changes `this`. ### React class component with bind and arrow class field ```javascript class UserProfile extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; this.handleClick = this.handleClick.bind(this); // manual bind for regular method } handleClick() { this.setState({ count: this.state.count + 1 }); // this = instance via bind } handleArrow = () => { this.setState({ count: this.state.count + 1 }); // this = instance automatically }; render() { return <button onClick={this.handleArrow}>{this.state.count}</button>; } } ``` Both approaches work. The arrow class field is cleaner and skips the constructor boilerplate. The bound method shares the implementation across instances via the prototype. In practice, most teams default to arrow fields. The per-instance function overhead is negligible for UI components. ### Lost `this` in Express middleware ```javascript app.use((req, res, next) => { const logger = { userAgent: req.get('User-Agent'), log: function() { console.log(this.userAgent); // undefined, this = global inside setTimeout } }; setTimeout(logger.log, 0); // broken setTimeout(() => logger.log(), 0); // works: arrow calls log as a method of logger next(); }); ``` The arrow wrapper `() => logger.log()` does not pass a bare function reference. It calls the method directly on the object, keeping the binding intact. This pattern comes up frequently in async middleware and queue processors where function references get passed around.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.