Created
April 17, 2012 16:54
-
-
Save gordonbrander/2407459 to your computer and use it in GitHub Desktop.
JavaScript Method Composition
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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