One thing that I think would be cool is if JavaScript provided a way to pass arguments to a function by name. About two years ago I wrote the code for a Function.prototype.invoke but never released it as part of jPaq like I had hoped. Recently, I decided to re-use the code I wrote and improve it. The following defines a Function.prototype.index function which enables parameter passing by name:


/**
 * @license Copyright 2013 - Chris West - MIT Licensed
 */
(function(reComments, reParams, reNames) {
  Function.prototype.index = function(arrParamNames) {
    var fnMe = this;
    arrParamNames = arrParamNames
      || (((fnMe + '').replace(reComments, '')
           .match(reParams)[1] || '')
          .match(reNames) || []);
    return function(namedArgs) {
      var args = [], i = arrParamNames.length;
      args[i] = namedArgs;
      while(i--) {
        args[i] = namedArgs[arrParamNames[i]];
      }
      return fnMe.apply(this, args);
    };
  };
})(
  /\/\*[\s\S]*?\*\/|\/\/.*?[\r\n]/g,
  /\(([\s\S]*?)\)/,
  /[$\w]+/g
);

Now let’s look at an example of using this code. Let’s define a function which accepts four parameters and prints the value of each parameter to the console:


var showA2D = (function(a, b, c, d) {
  console.log('a = ', a);
  console.log('b = ', b);
  console.log('c = ', c);
  console.log('d = ', d);
}).index();

Now we have our function and believe it or not but all we had to do was surround the function definition in parentheses and calls its index function to make it accept parameters by name. Now let’s call the function with some arguments:


showA2D({
  a: "first parameter",
  d: "last parameter",
  b: "second parameter"
});

Executing the above will print the following in the console:


a =  first parameter
b =  second parameter
c =  undefined
d =  last parameter

Another interesting thing we could have done when we defined showA2D was actually define the mapping of the parameters. This is especially useful if you plan on minifying the function which will be indexed. The following shows how we can map the arguments:


// Define the function.
var showA2D = (function(a, b, c, d, args) {
  console.log('a = ', a);
  console.log('b = ', b);
  console.log('c = ', c);
  console.log('d = ', d);
  console.log('args = ', args);
}).index(['a', 'b', 'c', 'd']);

// Call the new function.
showA2D({
  a: "first parameter",
  d: "last parameter",
  c: "third parameter"
});

After running the above code something like the following will be shown in the console:


a =  first parameter
b =  undefined
c =  third parameter
d =  last parameter
args =  Object {a: "first parameter", d: "last parameter", c: "third parameter"}

As you may have determined the Function#index function takes an optional Array which should contain the names of the parameters which will be mapped to the function. Another thing that is important to note is that the object that is passed to the indexed function will be passed to the original function as the final parameter.

If I ever get around to publishing the next version of jPaq this will probably make its way into the codebase. Until then, feel free to use this version (just give me some credit ;)).


Leave a Reply

Your email address will not be published. Required fields are marked *