4

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

var myFunction = function(funParameter) {
    // funParameter is a function
};

我可以这样调用这个函数:

myFunction(function (aParameter, anotherOne) {
    // do stuff
});

在 的正文中myFunction,如何检索funParameter应该接收的参数?我想知道使用传递给的函数声明的参数myFunction(在上述情况下,我想知道参数函数接受aParameteranotherOne.

我知道这样做的唯一方法是适当地解析funParameter.toString(),但我觉得这有点 hacky。

它应该像在 Mocha 测试中一样:

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

it如果您传递给的函数是否接受done参数,您必须能够表现得不同。

4

3 回答 3

3

你要的是这个。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length

除非参数名称保证在整个代码中保持一致并且永远不会以任何方式进行修改,否则您不想检查参数是否已命名,'done',大多数情况下,开发人员应该可以自由命名他们的函数参数.

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

但是,您更愿意做的是决定函数指定了多少个参数,并且可以通过Function.length.

然而,这也不是一个可靠的解决方案,因为你总是不能指定任何东西,仍然可以使用arguments.

在 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 */
于 2013-09-04T21:53:15.770 回答
1

如果您正在寻找具体的 Mocha 是如何做到的,请查看源代码

我深入研究了一下,发现 Mocha 只是检查传递函数的长度属性,正如您在此源文件中看到的那样。然后他们对 async 属性进行 if 检查,如下所示。如果 async 为真,它会以不同的方式调用测试函数来处理测试函数的异步特性。

this.async = fn && fn.length
于 2013-09-04T22:12:33.080 回答
0

获取函数参数Function.prototype.toString确实很麻烦。到目前为止,尽管不在规范中,但我测试过的所有浏览器都很好地支持它,AngularJS 使用它通过无序的参数名称映射请求的控制器功能。

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

    return params;  // ['aParameter', 'anotherOne']
}

*源修改自'functools'

于 2013-09-04T21:48:52.470 回答