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.