Using ExtJs‘ bind to partially apply a function

Because of my work I dabbled a bit in ExtJs and I wanted to show you something that I need quite regularly. It has become common practice in JavaScript to pass around function object like no man’s business. Which is quite alright. But sometimes you prepare a function for another library. Usually this looks something like this:

var somefunction = function (arg1, arg2, arg3, arg4, arg5) {
  console.log(arg1, arg2, arg3, arg4, arg5);
};

var caller = function (fObject) {
  return fObject(1,2);
};

caller(somefunction);
// 1 2 undefined undefined undefined

But you can’t pass any argument to somefunction (because JavaScript is not Haskell and you cannot build partially applied thunks). So how do we partially apply some values? ExtJs gives us quite a powerful tool:

caller(Ext.bind(somefunction, undefined /* this is the bound scope which, in this case, is not needed */, [3,4,5], true));
// 1 2 3 4 5

Usually, you would bind the scope to „this“ but in this rather trivial case, we don’t need it. The „true“ at the end is to tell Ext to append the new parameters (3, 4 and 5) rather than overwriting the existing ones. But we can put them any place we want.

caller(Ext.bind(somefunction, undefined, [3,4,5], 1));
// 1 3 4 5 2

We also can, which is rather cool, apply them in instead and therefore „cancel out“ other paramters by leaving the last bind-parameter as undefined:

caller(Ext.bind(somefunction, undefined, [3,4,5]));
// 3 4 5 undefined undefined

You can, of course, save your partially applied function objects:

var partiallyAppliedFunction = Ext.bind(somefunction, undefined, [3,4,5]);
partiallyAppliedFunction();
// 3 4 5 undefined undefined

But remember: The function is saved as reference at binding time (and not by name). Therefore changing the original function won’t change anything:

somefunction = function () { console.log('I no longer do as I am told.') };
partiallyAppliedFunction();
// 3 4 5 undefined undefined

You can also construct function objects from anonymous functions/closures that way, for whatever reason you would need that:

var SomeBoundAnonymousFunction = Ext.bind(function (a) { console.log(a); }, undefined, [3,4,5]);
SomeBoundAnonymousFunction();
// 3

cool, huh?!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

This site uses Akismet to reduce spam. Learn how your comment data is processed.