Skip to content

Instantly share code, notes, and snippets.

@gordonbrander
Created April 17, 2012 16:54
Show Gist options
  • Save gordonbrander/2407459 to your computer and use it in GitHub Desktop.
Save gordonbrander/2407459 to your computer and use it in GitHub Desktop.
JavaScript Method Composition
// In JavaScript, we can treat `this` as an implied first argument that can be
// set via `Function.prototype.bind`, `Function.prototype.call` or
// `Function.prototype.apply`. If we treat `this` as an argument containing a
// value that should be operated on and returned, a number of benefits emerge:
//
// * All methods of an object can be easily chained, jQuery style.
// * It reduces the confusing nature of side-effects in JavaScript OOP by taking the
// implicit `this` object and treating it as an explicit data object to be
// operated on.
// * Any method of an object that returns
// `this`, or a compatible object can be composed.
//
// This approach is exactly what makes jQuery so expressive.
//
// So anyway, here is a function composition method that treats `this` as an
// implied first argument.
// The return value of the previous function will become the `this`
// context object for the next function.
//
// All other arguments will be passed along, but aren't
// intended to be operated on.
//
// var o = {};
// o.f1 = function (x) { ... return this; };
// o.f2 = function (y) { ... return this; };
// o.f3 = function (z) { ... return this; };
// o.fff = chain(o.f1, o.f2, o.f3);
// o.fff(42);
//
// ...is equivalent to:
//
// o.f1(42).f2(42).f3(42);
//
var chain = function() {
var funcs = arguments;
return function() {
var context = this;
for (var i = 0; i < funcs.length; i++) {
// The arguments passed to the next function is the return value
// of the previous function, plus the "rest" of the context arguments.
context = funcs[i].apply(context, arguments);
}
return context;
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment