Modern JavaScript: Bind
Welcome to the Bind lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
In shorthand method bodies,
thisrefers to the object that contains that method.>
const user = {name: 'Amir',userName() { return this.name; }};user.userName();Result:
'Amir'
Sometimes we need to force a function to have a certain
this. We can do that using functions'bindmethod, likesomeFunction.bind(someNewThis). That gives us a new version of the function withthisbound to our specified value.Here's an example. First, we'll try to call a function that references
this, butthisisn't bound to anything. That's an error.>
const user = {name: 'Amir'};function userName() {return this.name;}userName();Result:
TypeError: Cannot read properties of undefined (reading 'name')
The error happens because
thisisundefined, which has nonameproperty. If we binduseras the function'sthis, then we can access its name.>
const user = {name: 'Amir'};function userName() {return this.name;}const userNameBound = userName.bind(user);userNameBound();Result:
'Amir'
We don't have to introduce a temporary variable to hold the bound function; we can do it as a single expression. We call
.bind()to get the bound function, then we call that bound function. The example below is equivalent to the one above.>
const user = {name: 'Amir'};function userName() {return this.name;}userName.bind(user)();Result:
'Amir'
Here's a code problem:
Use
bindto call thegetAddressStringfunction withaddressbound tothis.function getAddressString() {return `${this.city}, ${this.country}`;}const address = {city: 'Paris',country: 'France',};getAddressString.bind(address)();- Goal:
'Paris, France'
- Yours:
'Paris, France'
Let's see a more realistic example of where we might use
bind. We've seen shorthand methods defined using the syntaxfunctionName() { ... }. They have athisthat refers to the parent object.>
const address = {city: 'Paris',country: 'France',addressString() { return `${this.city}, ${this.country}`; },};address.addressString();Result:
'Paris, France'
What happens if
addressStringreturns a function instead of returning the string directly? ThethisinaddressStringreferences its wrapperaddressobject. However, the inner function has its own, distinctthis. As a result, the inner function'sthiswill beundefined.>
const address = {city: 'Paris',country: 'France',addressString() {return function() {return `${this.city}, ${this.country}`;};},};address.addressString()();Result:
Depending on where you run that example – in a browser, at a Node REPL, or in another environment – you may see a different error message. In your case,
thismight refer towindoworundefined. But you can be sure that it won't refer to theaddressobject.Fortunately, we can use the
bindmethod to manually set our inner function'sthis:>
const address = {city: 'Paris',country: 'France',addressString() {const f = function() {return `${this.city}, ${this.country}`;};return f.bind(this);},};address.addressString()();Result:
'Paris, France'
This might seem awkward. It is! There's usually a less awkward way to solve the problem, so
bindshould be used sparingly. But occasionally,bindreally is the right tool for the job.When you're tempted to use
bind, we recommend searching for another solution, then usingbindonly as a last resort. In another lesson, we'll cover arrow functions, which can solve theaddressStringproblem shown above without usingbind.