Recently I looked at dependency injection and wrote heroin. Mostly I targeted heroin to perform the dependency injection by name, but it can be useful to do plain argument binding. It is a nice complement to the two functions already provided by the excellent lodash library.
_.partial
If we want to bind a few arguments in left to right order, we can use _.partial that constructs a new function
1 | var add = function(a, b, c) { return a + b + c; }; |
addC
is a function that expects a single input (value of c
), it is same as writing
1 | var addC = function (c) { |
I often use left to right argument binding when working with promises. Promises resolve / reject with a single value, so any additional information to be passed around needs to be bound before hand.
_.partialRight
If we want to bind arguments at the end of the function, we can use _.partialRight. We still list the values left to right though:
1 | var add = function(a, b, c) { return a + b + c; }; |
In this case b
will be 10 and c
will be 20, leaving the first argument a
free.
heroin = _.partialSome
I prefer to bind arguments by name, rather than index. To do this, I extend lodash with _.mixin function
1 | _.mixin({ |
Using this approach leaves me free to refactor the argument order in add
function,
since it will no longer break the partial argument binding. I could even bind all arguments:
1 | var sum = _.partialSome(add, { |
By reference
heroin only creates a link between the argument name and the object. Since objects in JavaScript are passed by reference, you can change the value of the injected parameter at any time
1 | var args = { |
This is very flexible but can lead to the unexpected results. If you want to prevent accidental changes to the arguments, you can either clone or freeze the top level object
1 | var args = { |
Valid input functions
All partial binding functions expect a function with valid arity (number of arguments)
to work correctly. For example, _.partialRight
cannot work if the input function
does not list its arguments
1 | var add = function() { |
Only functions with valid .length
value can be used.
Returned function
Because the returned proxy function is constructed dynamically using
arguments
array, it does not list its arguments, and thus cannot be used
as input to the partial binding itself!
1 | var addC = _.partialRight(add, 1); // bind c, leave a and b |
One could get around this by compiling the proxy function from source text, but I think this would be terribly non optimizeable
1 | // inside _.partialRight implementation |