Bind Confusion and how to use it

challenge:

Consider the following:

const driver = {
  name: 'Danica',
  displayName: function () {
    console.log(`Name: ${this.name}`);
  }
};

const car = {
  name: 'Fusion'
};

Write an expression using bind() that allows us to “borrow” the displayName() method from driver for the car object to use. Note: The expression itself is sufficient (no need to save it to a variable).

I wrote the below, which passed the test:

driver.displayName.bind(car)

however I still dont understand so does bind not make the driver.displayname() method now available to car??
how come then when I write:

console.log(car);
//Object {  name: "Fusion"}

why does the car object now NOT have a displayName method on it??
I thought that bind would allow the displayName method to be called on car. Is this not correct? yet we see that car still does not have a displayName method. I guess I do not understand what bind really does. All advice appreciated.

If this is covered in the fcc curriculum please refer to it.

2 Likes

The MDN docs are very great, and possibly the best. Read them first!

So, driver.displayName.bind(car) creates a new function with the car object set to this keyword.
In your example, we only created a function that we didn’t use/call/ or store it in any variable to use it later.
Perhaps the following example would make more sense

const newFunction = driver.displayName.bind(car);
/*
  now you can call `newFunction();` and 
  it would run the function that you just created with `bind`
  And as you are accessing `this.name`, it would access
  the `this` value from the `car` object.
  The `car` object does not own this function. This is a NEW FUNCTION!
  independent of `driver` and `car` objects now.
*/

To demonstrate a little bit more, let’s create a newFunction with bind, then remove the displayName property from your driver object, so it doesn’t have any function to call at all. But the newFunction would still work fine because it doesn’t depend on either of the objects now. Try this in your browser console:

var driver = {
  name: 'Danica',
  displayName: function () {
    console.log(`Name: ${this.name}`);
  }
};
var car = {
  name: 'Fusion'
};

const newFunction = driver.displayName.bind(car);
delete driver.displayName;

console.log(driver.displayName); // logs: `undefined`, as we no longer have the function

newFunction(); // logs: `Name: Fusion`
// It worked even though we don't have any 
// function in both of our objects at all.
2 Likes

So within car, you can create properties, right? What if you were to create a property with the name, oh, say… displayName? And what might you set that to? You could, if you were so inclined, set that to something like driver.displayName (note that, without the parenthesis, I’ve set the function itself to the object property). And that’s great and all, but there’s still the issue of context.

Context is a big and ugly beast that has devoured many a hale and hardy javascript developer. It’s easy to lose context. What is context? When a function is called, it is called in reference to … something. If, for example, I were to call myArray.push("foo"), I have called the object method .push() in the context of myArray. If I call driver.displayName(), then I would be calling the function displayName in the context of driver.

But what if there were a way to run a function from somewhere else, in the context of any other object? that would be cool, right? In fact, that’s pretty much how mixins work. A great feature, lets you take an object that you define as a means of storing a whole library of utility functions, and run them in the context of your unique object.

In your case, in the case of car, we have a context (the car object), and we have a a function we’re planning to pull in from somewhere else (the driver object). How about if we were to create a property on car that points to the method on driver we want, but make sure it doesn’t know about the driver context? That would be, like, AMAZING!!

And that’s what .bind() does for us. It tells a given function, taken from somewhere else, to run in the context it is given. So we could, in fact, do something just like this:

const car = {
  name: "Prius",
  displayName: driver.displayName.bind(this)
}

Now, that gets into the question of what’s this? And that’s a whole discussion. this is, in fact, the current context. In the above block of code, this refers to the car object that we’ve defined. By binding a function from somewhere else to a variable in the local context, we tell it to run as though it were a local function to our car object.

Pretty neat, and confusing as ANYTHING. Best place to research things like this? As @husseyexplores has suggested, MDN is a very powerful, very complete resource. Also, and one I highly recommend as you move forward, http://devdocs.io/ is a great collection of a lot of different programming resources, all in one unified interface.

2 Likes