Functions are Objects
Passing methods around
The snippet above uses a data object and a function handler to update the state of the UI. The pattern is quite similar to what is followed in some major web frameworks. The method “changeCount” is passed as an event handler to the input box.
In the case 1, where we do not specify explicit binding, “this” reference in the method is referring to the HTML element and not the data object which leads to error. The error occurs because we are trying to refer “counter” from the method which is not a part of the HTML Element.
In the case 2, we fix that by explicitly binding the “data” object using the following. With this let’s define the bind method.
document.getElementById("newage1").onkeyup = data.changeCount.bind(data);
Defining the bind method
The above example clears the air a little bit. Now, let’s look underneath. The bind method sets the value of “this” keyword to what is specified and returns a new function. If you have played with the snippet above, you might notice that even though you had set the bind method in the case 2, it didn’t change the definition of the “changeCount” method, it rather created a “new function” and sent it over to only the 2nd input box. The bind method is expressed as follows.
<var>fun</var>.bind(<var>thisArg</var>[, <var>arg1</var>[, <var>arg2</var>[, ...]]])
This brings to another important aspect of “bind”, the “currying”.
Function Currying and Binding
In the snippet above, the function “updateCounter” is a curried function which returns a new partially applied function where one of the arguments is already pre-filled. Here’s how the results look like.
“bind” offers a quick and convenient way of creating the curried function by applying some of the arguments of a function. Here’s a re-write of the above example.
The first argument to the “bind” method is the “this” reference followed by any number of arguments we want to preset. Since we are not using “this”, we have set it to “null”.
Currying and binding “this”
With “bind”, as we curry function, we can reuse the function with multiple execution context/objects with different preset values. Let’s look at an example.
In the snippet above, we have 2 separate counters and we want to increment the 2 counters based on different multiplying factors. With the help of currying we can create a single function “updateCounter” and bind it to the 2 counter instances with the different multiplying factor. Remember, the first argument is the “this” reference. Here’s a snapshot of the result.
Binding the Callbacks
setTimeout, by default is bound to the global object. However, in case a callback needs a reference to an object, it has to be bound to the object. Here’s an example.
In the snippet above, there are two methods “runUnboundTimer” and “runBoundTimer”. Both of the methods use the “setInterval” function which by default is bound to the global object. Since the “runUnboundTimer” do not do any explicit binding, the callback method “incrementCount” cannot find out the counter value. We fix that bind by explicitly binding the target object. Here’s a result snapshot of the above snippet.