Function 在JavaScript中检索函数参数的名称

Function 在JavaScript中检索函数参数的名称,function,javascript,Function,Javascript,我有一个JavaScript函数,它接受一个函数作为参数,如下所示: var myFunction = function(funParameter) { // funParameter is a function }; myFunction(function (aParameter, anotherOne) { // do stuff }); 我可以这样调用此函数: var myFunction = function(funParameter) { // funPar

我有一个JavaScript函数,它接受一个函数作为参数,如下所示:

var myFunction = function(funParameter) {
    // funParameter is a function
};
myFunction(function (aParameter, anotherOne) {
    // do stuff
});
我可以这样调用此函数:

var myFunction = function(funParameter) {
    // funParameter is a function
};
myFunction(function (aParameter, anotherOne) {
    // do stuff
});
myFunction
的主体中,如何检索
funparmeter
应该接收的参数?我想知道传递给
myFunction
的函数所声明的参数(在上述情况下,我想知道参数函数接受
a参数
另一个参数

我知道这样做的唯一方法是正确地解析
funParameter.toString()
,但我觉得这有点像黑客

这应该像摩卡咖啡测试一样:

it('should test something synchronously', function () {...});
it('should test something asynchronously', function (done) {
    // test...
    done();
});

如果传递给
的函数接受或不接受
done
参数,则必须能够表现出不同的行为。

通过
函数获取函数参数。prototype.toString
确实是一种黑客行为。到目前为止,尽管不在规范中,但我测试过的所有浏览器都非常支持它,Angula也使用它rJS通过无序参数名称映射请求的控制器功能

function myFunction(func) {
    var params = func.toString()
        .match(/function\s*.*\((.+)\)/)[1]
        .split(',');

    return params;  // ['aParameter', 'anotherOne']
}
*源模式化自

您想要的是这个

除非保证参数名在整个代码中保持一致,并且不会以任何方式进行调整,否则您不想检查参数是否命名为“done”,大多数情况下,开发人员应该可以自由命名其函数参数

此外,javascript代码(用于浏览器)通常是丑陋和混乱的,并且参数名称被缩短。如果名称被更改,它将破坏您的功能

this.async = fn && fn.length
但是,您需要做的是确定函数指定了多少个参数,这可以通过
function.length
完成

但是,这也不是一个可靠的解决方案,因为您始终不能指定任何内容,并且仍然可以使用
参数
获取参数值

在JavaScript中,假设某些东西会以我预期的方式工作通常是个坏主意,因为你永远不知道谁会用他们的代码做什么

语言本身在很多方面都是动态的,在设计函数/API之前,您必须非常小心

来自MDN:

console.log( (function () {}).length );  /* 0 */
console.log( (function (a) {}).length ); /* 1 */
console.log( (function (a, b) {}).length ); /* 2 etc. */
console.log( (function (...args) {}).length ); /* 0, rest parameter is not counted */

如果你特别想知道摩卡咖啡是怎么做的,看看下面的例子

我深入研究了一下,发现Mocha只是在检查传递函数的length属性,如图所示。然后,他们对async属性执行if检查,如下所示。如果async为true,它将以不同的方式调用测试函数,以处理测试函数的async性质

this.async = fn && fn.length

我想你被困在了
toString
…好吧,没有别的办法了。我对这个问题很感兴趣(so+1),但我看着它,忍不住想(沿着“天哪,你到底在做什么,为什么?”@DavidThomas:)没关系,这对我来说也很不舒服。但是,嘿,看看Mocha测试套装中的
it
函数:他们到底是怎么做到的?这是解决问题的一种方法,但你可能需要命名参数,就像AngularJS(前面的答案中提到的那样)。“你不想检查参数是否命名为'done'”——好吧,这完全取决于你试图做什么。AngularJS的功能类似于OP要求的依赖注入。参数的数量和顺序无关紧要,重要的是名称。另一个例子是John Resig的tmpl使用
toString
on函数来查找
super
类。这不是一个可靠的解决方案。如果代码变丑了,参数名也变了怎么办;我的意思是说,如果OP有一种情况,其中参数的名称很重要(并且没有关于原因的进一步信息,很难反驳这种需要),那么我倾向于认为这是必要的。千方百计提出反对需要或使用的论据,或提出替代方案;但是要声明您不想检查参数是否命名为“done”,这有点自以为是(而且您反对的论点实际上没有太大的份量,尽管是“imho”等等)。同样,“John Resig doit”也不正确。我尊重John Resig及其所做的一切,但他提出的解决方案不应用于浏览器库。好吧,我很害怕。不管怎样,如果函数没有参数或间隔参数,那么您的函数就是有缺陷的?这应该更好:
function-pars(fun){return-fun.toString.match(/function.*?\(.*?\)/)[1].split(',').map(function(el){return-el.trim();})}
Wow,它在注释中看起来不太好。我会编辑你的答案。