JavaScript函数参数:位置->;映射转换

JavaScript函数参数:位置->;映射转换,javascript,function,dictionary,syntax,arguments,Javascript,Function,Dictionary,Syntax,Arguments,我正在寻找一个普通的JavaScript解决方案 假设我有一个具有以下标题的函数: generateEmail(firstName, lastname, provider) 我需要这样运行它: generateEmail("John","Smith","gmail.com"); 我希望能够使用参数映射而不是位置参数调用它,即 generateEmail({ "firstName":"John", "lastname": "Smith", "provider": "gmail.co

我正在寻找一个普通的JavaScript解决方案

假设我有一个具有以下标题的函数:

generateEmail(firstName, lastname, provider)
我需要这样运行它:

generateEmail("John","Smith","gmail.com");
我希望能够使用参数映射而不是位置参数调用它,即

generateEmail({
  "firstName":"John",
  "lastname": "Smith",
  "provider": "gmail.com"
});
我正在寻找一个已经编写好的解决方案来用JavaScript实现这一点,因为我有无数的函数要处理,比如上面的generateEmail。有这样的图书馆吗

我已经看到了处理函数内省(返回函数抽象参数信息)的方法。但是第二部分是缺失的——将映射调用映射到位置调用

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


编辑:如果我没有说清楚:我不想修改原始的位置参数函数。我从一个外部提供者那里得到这样的函数,这个提供者可能会更新他的代码。我更希望有一个可以调用下面原始函数的包装器,并在外部提供映射参数API

   var orig_generateEmail = generateEmail;
   var generateEmail = function (map) {
              orig_generateEmail(map.firstName, map.lastname, map.provider);
   };

但是,这显然会在静态“映射”列表中结束。

假设您可以从中访问
内省
(它接受一个函数并返回一个有序的参数名称列表),您只需执行以下操作:

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"
});
它接受一个函数,读取其参数名,然后返回一个包装函数,该函数接受一个对象,并使用位置参数名以正确的顺序从对象参数中提取属性


此函数使用调用时间对象参数作为映射,将数组
[“firstName”、“lastname”、“provider”]
转换为数组
[“John”、“Smith”、“gmail.com”]
。然后将该数组与
apply
一起使用,以调用positional argument函数。

而不使用任何外部库

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);
}
var STRIP\u COMMENTS=/(\/\/.$)|(\/\*[\s\s]*?\*\/)/mg;
变量参数名称=/([^\s,]+)/g;
函数getParamNames(func){
var fnStr=func.toString().replace(带注释“”);
var result=fnStr.slice(fnStr.indexOf('(')+1,fnStr.indexOf(')).match(参数名称);
如果(结果===null)
结果=[];
返回结果;
}
函数调用(方法、对象){
var params=getParamNames(方法);
var arrParams=[];
对于(变量i=0;i

只要用
call(generateEmail,generateEmailObject)

调用它,你就可以检查
firstName
是否是一个对象,然后用正确的参数再次调用
generateEmail
。@GaurangTandon这完全是我不需要的。我需要一个通用的包装器函数来处理我写的东西。我可以自己写,但首先我想检查一下,这样的东西是否已经存在。我想说,结合使用这个和
.apply
,这是可能的。@EvanKnowles我知道这个链接,我知道如何使用
.apply
;主要是我知道如何写这样的东西,但我不喜欢重新发明轮子:)我更喜欢使用现有的解决方案。比我的解决方案整洁得多。我希望有一个库来处理它,我只是不想重新发明轮子。无论如何,你的解决方案是针对我的需要;我在想:
var argMapify=function(fn,argValues,context){var argDefs=introspect(fn);return fn.apply(context,argDefs.map(function(arg){return argValues[arg];}));}
和调用
argmapifn(fn,{…}
,,因为您从外部供应商处获得函数,并且可以动态调用该函数。请注意使用
节点内省
,因为它将函数解析为字符串。任何超出其正则表达式范围的内容(在将来的这里,我们有带可选括号的ES6单参数箭头函数)都将无法解析。简言之,如果您在实际使用中考虑到这一点,请小心。