Paulo Phagula

Musings and Scribbles on Software Development

Simple JavaScript Currying Using bind

In this blog post I tell you a short story about how I was introduced to JavaScript function currying"

I was working on a nodejs project with mighty @giannis and we had this library that required setting up event handlers, pretty much in the usual form of:

libObject.on('event', function(param) {
    // handling code using the same libObject.
    // It's very important and compulsory using libObject here.
    return libObject.someMethod();
});

No issues with that, but a new business requirement lead us to need many instances of that libObject.

I thought about it the naive way and created an array with the libObjects, then extracted the handler functions into standalone functions I could set in each of the libObject pretty much like:


var libObjectCollection = {};

var handlerfn = function(param) {

};

for (var key in libObjectCollection) {
    libObjectCollection[key].on('event', handlerfn);
}

And that is where the challenge begun, as in the handlerfn I could no longer know which libObject instance I should call.

That’s when might @giannis told me:

mate, just use “bind” on the handlerfn, and pass in the key/id of the instance you want.

Well, I already knew that functions are first class objects in JavaScript, and that they can be passed around, and even have methods called on them. Specifically I already knew about call and apply, but I had never had a case in which bind was needed.

So, first stop.. MDN.

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

that meant I could go like:


var handlerfn = function(libObject, param) {

};

for (var key in libObjectCollection) {
    libObjectCollection[key].on('event', handlerfn.bind(null, libObjectCollection[key], param));
}

The first parameter into the bind method is the new this or context under which the returned function will run when called in the future.

Following is the key I need for libObject and last is whichever params the library will pass into the fn when calling.

Last but not least, as I pointed above … this was the the naive way… In the very end, since this was a NodeJS project and we were already using PM2, we just created n different processes each with it’s own configuration and didn’t need to change the code.

Despite that I’m thankful I found this issue for now I’ve learned this lesson. BTW, in FP circles developers call this thing we tried to do with bind currying.



Please, use syntax highlighting in your comments, to make them more readable.