Execute Program

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, this refers to the object that contains that method.

  • >
    const user = {
    name: 'Amir',
    userName() { return this.name; }
    };
    user.userName();
    Result:
    'Amir'Pass Icon
  • Sometimes we need to force a function to have a certain this. We can do that using functions' bind method, like someFunction.bind(someNewThis). That gives us a new version of the function with this bound to our specified value.

  • Here's an example. First, we'll try to call a function that references this, but this isn'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')Pass Icon
  • The error happens because this is undefined, which has no name property. If we bind user as the function's this, then we can access its name.

  • >
    const user = {name: 'Amir'};
    function userName() {
    return this.name;
    }
    const userNameBound = userName.bind(user);
    userNameBound();
    Result:
    'Amir'Pass Icon
  • 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'Pass Icon
  • Here's a code problem:

    Use bind to call the getAddressString function with address bound to this.

    function getAddressString() {
    return `${this.city}, ${this.country}`;
    }
    const address = {
    city: 'Paris',
    country: 'France',
    };
    getAddressString.bind(address)();
    Goal:
    'Paris, France'
    Yours:
    'Paris, France'Pass Icon
  • Let's see a more realistic example of where we might use bind. We've seen shorthand methods defined using the syntax functionName() { ... }. They have a this that refers to the parent object.

  • >
    const address = {
    city: 'Paris',
    country: 'France',
    addressString() { return `${this.city}, ${this.country}`; },
    };
    address.addressString();
    Result:
    'Paris, France'Pass Icon
  • What happens if addressString returns a function instead of returning the string directly? The this in addressString references its wrapper address object. However, the inner function has its own, distinct this. As a result, the inner function's this will be undefined.

  • >
    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, this might refer to window or undefined. But you can be sure that it won't refer to the address object.

  • Fortunately, we can use the bind method to manually set our inner function's this:

  • >
    const address = {
    city: 'Paris',
    country: 'France',
    addressString() {
    const f = function() {
    return `${this.city}, ${this.country}`;
    };
    return f.bind(this);
    },
    };
    address.addressString()();
    Result:
    'Paris, France'Pass Icon
  • This might seem awkward. It is! There's usually a less awkward way to solve the problem, so bind should be used sparingly. But occasionally, bind really is the right tool for the job.

  • When you're tempted to use bind, we recommend searching for another solution, then using bind only as a last resort. In another lesson, we'll cover arrow functions, which can solve the addressString problem shown above without using bind.