JavaScript函数参数:位置 - >地图过渡

时间:2015-05-04 12:26:28

标签: javascript function dictionary syntax arguments

我正在寻找 vanilla JavaScript 解决方案。

说我有一个带有以下标题的函数:

generateEmail(firstName, lastname, provider)

我需要像这样运行它:

generateEmail("John","Smith","gmail.com");

我希望能够用参数图而不是位置参数来调用它,即

generateEmail({
  "firstName":"John",
  "lastname": "Smith",
  "provider": "gmail.com"
});

我正在寻找一个已经编写好的JavaScript解决方案,因为我已经拥有无限数量的功能,例如上面的 generateEmail 来处理。这样的图书馆存在吗?

我见过https://github.com/kilianc/node-introspect处理函数内省(返回函数抽象参数信息)。但第二部分缺失 - 将map-call映射到位置调用。

请告诉我,这样的事情是否存在。

编辑:如果我没有说清楚:我不想修改原始的位置参数功能。我从外部提供程序获得这些函数,可以更新他的代码。我更喜欢有一个可以调用下面的原始函数的包装器,并在外面提供map-argument API。

3 个答案:

答案 0 :(得分:3)

假设您可以从node-introspect访问introspect(它接受一个函数并返回一个有序的参数名称列表),您可以这样做:

function objArgsify(fn) {
    var argNames = introspect(fn);
    return function(obj) {
        return fn.apply(this,
                        argNames.map(function(a) { return obj[a]; });
    }
}

通过以下方式调用:

var generateEmailWithObjArgs = objArgsify(generateEmail);
generateEmailWithObjArgs({
  "firstName":"John",
  "lastname": "Smith",
  "provider": "gmail.com"
});

它接受一个函数,读取它的参数名,然后返回一个接受一个对象的包装函数,并使用位置参数名以正确的顺序从object-argument中提取属性。

此函数使用call-time object-argument作为映射将数组["firstName", "lastname", "provider"]转换为数组["John", "Smith", "gmail.com"]。然后该数组与apply一起使用以调用postional-argument函数。

答案 1 :(得分:2)

不使用任何外部库,

var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
function getParamNames(func) {
  var fnStr = func.toString().replace(STRIP_COMMENTS, '');
  var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
  if(result === null)
     result = [];
  return result;
}

function call(method, object) {
    var params = getParamNames(method);
    var arrParams = [];
    for (var i = 0; i < params.length; i++) {
        arrParams.push(object[params[i]]);
    }
    return method.apply(arrParams);
}

只需使用call(generateEmail, generateEmailObject)调用它。

答案 2 :(得分:0)

这样的东西
   var orig_generateEmail = generateEmail;
   var generateEmail = function (map) {
              orig_generateEmail(map.firstName, map.lastname, map.provider);
   };

但显然最终会出现在静态&#34;映射列表中#34;。