djechlin
djechlin

Reputation: 60788

Bind arguments in different order

Say I have

function bake(egg, milk, batter) { ... }

And I already have the egg. Then I might do this

var f = bake.bind(null, theEgg);

to create a function that does the rest of the work.

But: what if I have the milk or the batter and I want to bind it, and it's the first argument that will be passed in later? Is there a functional way to twist the arguments without just creating an anonymous intermediary function and manually twisting the arguments so I can have fluid, functional-looking code with the argument bound?

Upvotes: 1

Views: 832

Answers (2)

elclanrs
elclanrs

Reputation: 94121

I think you're looking for partial application, with placeholder. Here's a helper:

var _ = {} // placeholder

var partial = function(f) {
  var as = [].slice.call(arguments, 1)
  return function() {
    var args = as.concat([].slice.call(arguments))
    for (var i=args.length; i--;)
      if (args[i] === _)
        args[i] = args.splice(-1)[0]
    return f.apply(null, args)
  }
}

Then you can use it like so:

partial(bake, _, theMilk, _)(theEgg, theBatter)

Upvotes: 3

jasonscript
jasonscript

Reputation: 6170

Using an object is usually the way to do this

var ingredients = {
    egg: theEgg,
    milk: theMilk,
    batter: theBatter
}

bake(ingredients);

Then you can vary the order in which egg, milk or batter are added to ingredients and you can handle null or undefined values within your bake method.

There are also libraries (e.g. jQuery extend) that allow you to merge 2 objects together, so for example, you could have a default set of ingredients that are extended with the values provided in the arguments

Upvotes: 0

Related Questions