bind. It is a great tool to give you control of the ever-squirrely
this keyword. Have you ever had trouble predicting what
this will be or making equate to what you want?
bind will help you do that with more power and consistency. It can also help you with partial function application.
this keyword refers to changes often. This can be useful but also unexpected. Generally
this, used within a function, will refer to the context in which that function was called. That calling context might be the global context of
window if an event callback is being called in a browser. That calling context might be an object that contains the function. For more specific cases, MDN has some great docs on the variety of contexts referred to by
When writing code, I often am thinking of
this in the context in which I’m writing. In other words, if I’m writing an object and use the keyword
this in a function, I would normally expect
this to refer to the object in which I declared the function. But, again, it is actually the calling context that actually determines the value of
To change this default behavior, I can pre-bind the function’s value of
this to a value of my choosing. This will happen at the time of declaration, which is what I more naturally would expect.
For example, in React we write UI components. In interesting UIs, we’re often handling events like those that occur with user interaction. Normally events in the browser are attached to the DOM and are executed in the context of the
window. This being the case, it’ll be hard for us to create an event handler function in our React Component that can refer back to anything of use in the React Component itself.
As a simple example, we’ll write a
handleClick function that wants to call the Component’s
doLog function for interesting logging:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
If you click the button,
this.doLog is not available as a function. How could it be?
doLog is defined in
MyComponent, not the
window, which is the original context in which the event callback is executed.
To fix this, one need only pre-bind the
handleClick function. By changing one line, we can fix this:
When this line is executed, it’s in the
MyComponent#render function, thus the
MyComponent context. So
this, at that moment, is
The other detail that makes this work is that
bind returns a brand new function. That’s how the pre-binding works. So, the
onClick prop that gets given to the
button is a new function where we have said we want to permanently control the value of
this to be whatever we bound it to.
Passing Specific Arguments with
Another great reason to use
bind is to pass specific arguments to a function. Just as
bind can create new functions where the value of
this is pre-determined (bound),
bind can pre-fill (ie, partially apply) function arguments on the newly-created function.
It may not be immediately intuitive why one would want to create a function with parameters just to turn around and permanently make it so an argument to the function equals a specific value. It almost feels like hard-coding a wart-ridden value on something that was previously dynamic and beautiful. Perhaps an example will help.
Again, to the world of React… As in the previous example, we’ll pass an event handler for a click event. Notice, just as above, that we’re passing the function itself (
this.handleClick above) instead of the return value of the function (which would look like
this.handleClick()). In this example, we’ll have several click handlers, each on a list item, where the button will function as a remove button:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
List, we have the event handler, the
handleClickRemove function, that takes an
index parameter. In order to make this function work as defined, we are using
bind on this line:
bind call is doing a few things for us:
ListComponent so that
this.setStateworks inside the callback.
- Creating a new function that always has
ias its first parameter. Since this line is executed in a loop,
ichanges. It will be
0for the first item,
2. This is perfect, as we want the first remove button to remove the first item, and so on.
Isn’t that awesome and useful?
bind can help make
this more predictable for you. It will help you send new functions with pre-filled parameters. What else have you used