Suggest an editImprove this articleRefine the answer for “Explicitly setting this in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**The context is set with three explicit methods: `call(thisArg, a, b)` and `apply(thisArg, [a, b])` invoke the function immediately, while `bind(thisArg)` returns a new function with a permanently bound `this`.** Besides these the context can be set implicitly: a dot call makes `this` the object itself, arrow functions inherit `this` from the enclosing scope, `Reflect.apply` is the modern counterpart of `apply`, and `new` always creates its own object and overrides even `bind`. ```javascript function greet() { console.log(`Hello, I am ${this.name}`); } const user = { name: 'Maria' }; greet.call(user); // immediately greet.apply(user, []); // immediately, arguments as an array greet.bind(user)(); // a new function, called later ``` **Key point:** `call` and `apply` invoke immediately, `bind` binds forever, and `new` takes priority over all of them.Shown above the full answer for quick recall.Answer (EN)Image**You can force `this` with the methods `call`, `apply` and `bind`, and also through calling the function as a method of an object, through arrow functions, `Reflect.apply` and the `new` operator.** The difference between them is when the call happens and whether the context can be changed afterwards. ## Theory ### TL;DR - `call(thisArg, a, b)` invokes the function **immediately**, arguments comma separated. - `apply(thisArg, [a, b])` does the same, but the arguments come **as an array**. - `bind(thisArg)` **does not invoke** anything, it returns a new function with a bound `this`. - `obj.method()` sets `this = obj` **implicitly**. - Arrow functions have no `this` of their own and take it from the enclosing scope. - `Reflect.apply(fn, thisArg, args)` is the modern counterpart of `apply`. - `new Func()` creates a new object and overrides even a `bind` binding. ### Quick example ```javascript function greet() { console.log(`Hello, I am ${this.name}`); } const user = { name: 'Maria' }; greet.call(user); // Hello, I am Maria ``` Here `this` inside `greet` is forced to point at `user`. ### call and apply: immediate invocation with a given context `Function.prototype.call()` invokes the function **immediately** and lets you **set `this` by hand**: ```javascript function greet() { console.log(`Hello, I am ${this.name}`); } const user = { name: 'Maria' }; greet.call(user); // Hello, I am Maria ``` `apply()` does the same thing as `call`, but takes the **arguments as an array**: ```javascript function introduce(city, job) { console.log(`I am ${this.name} from ${city}, working as a ${job}`); } const user = { name: 'Maria' }; introduce.apply(user, ['Kyiv', 'Frontend developer']); // I am Maria from Kyiv, working as a Frontend developer ``` ### bind: a new function with a bound context `bind()` does not invoke the function right away; it **creates a new one** whose `this` is already bound forever: ```javascript function sayHi() { console.log(`Hello, I am ${this.name}`); } const user = { name: 'Maria' }; const sayHiBound = sayHi.bind(user); sayHiBound(); // Hello, I am Maria ``` The difference: - `call` / `apply` **invoke immediately**; - `bind` **creates a copy with a fixed context**. ### Implicit context: object methods and arrow functions If you call a function **through the dot on an object**, `this` automatically points at that object: ```javascript const user = { name: 'Maria', sayHi() { console.log(`Hello, I am ${this.name}`); } }; user.sayHi(); // Hello, I am Maria ``` This is an **implicit assignment of `this`**, but in essence the same thing. Arrow functions have **no `this` of their own**: they inherit it from the enclosing scope: ```javascript const user = { name: 'Maria', sayHiLater() { setTimeout(() => { console.log(`Hello, I am ${this.name}`); // this = user }, 1000); } }; user.sayHiLater(); // Hello, I am Maria ``` Had a regular function been used inside `setTimeout`, `this` would have been lost and become `window`. ### Reflect.apply, new and deliberately dropping the context `Reflect.apply()` is the modern ES6 counterpart of `apply`: it does the same, but more safely and declaratively, because it does not depend on whether `apply` has been overridden on the function itself: ```javascript function sayHello() { console.log(`Hello, ${this.name}`); } const user = { name: 'Maria' }; Reflect.apply(sayHello, user, []); // Hello, Maria ``` When a function is called with `new`, a **new object** is created and `this` inside the function points at it, even if a different `this` was bound through `bind`: ```javascript function User(name) { this.name = name; } const Bound = User.bind({ name: 'Maria' }); const u = new Bound('Alice'); console.log(u.name); // Alice, the context from new overrides bind ``` If instead you want to "unbind" `this` and call the function without a context, you pass `null` or `undefined`: ```javascript function showThis() { console.log(this); } showThis.call(null); // under 'use strict' -> undefined ``` In sloppy mode `null` is substituted with the global object (`window` or `global`). ### Summary of the options | Way | Invokes immediately | How it sets `this` | Arguments | | --- | --- | --- | --- | | `call(thisArg, a, b)` | Yes | Forced | Comma separated | | `apply(thisArg, [a, b])` | Yes | Forced | As an array | | `bind(thisArg, a, b)` | No | Binds forever | Comma separated | | `obj.method()` | Yes | Implicitly (`this = obj`) | Comma separated | | `Reflect.apply()` | Yes | Forced (modern counterpart) | As an array | | `new Func()` | Yes | A new object inside the function | Constructor arguments | ### Common mistakes - **Binding `this` to an arrow function.** Arrows have no `this` of their own, so `call`, `apply` and `bind` have no effect on it and the first argument is simply ignored. - **Looking for `Reflect.call`.** No such method exists: `Reflect` only has `apply`, so the arguments always go in as an array. - **Assuming `bind` invokes the function.** It only returns a new function, and without parentheses nothing happens. - **Counting on `window` in strict mode.** In modules and classes `this` stays `undefined` when given `null`, so `this.name` throws. - **Losing the context when passing a method around.** `setTimeout(user.sayHi, 1000)` passes only the function without the object; you need `user.sayHi.bind(user)` or an arrow wrapper.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.