是否有一种方法可以动态地获取函数的函数参数名?
假设我的函数是这样的
function doSomething(param1, param2, .... paramN){
// fill an array with the parameter name and value
// some other code
}
现在,我如何从函数内部获得参数名称及其值的列表到数组中?
是否有一种方法可以动态地获取函数的函数参数名?
假设我的函数是这样的
function doSomething(param1, param2, .... paramN){
// fill an array with the parameter name and value
// some other code
}
现在,我如何从函数内部获得参数名称及其值的列表到数组中?
当前回答
注意:如果你想使用ES6参数解构与顶部解决方案添加下面的行。
if (result[0] === '{' && result[result.length - 1 === '}']) result = result.slice(1, -1)
其他回答
你可以使用"arguments"属性访问传递给函数的参数值。
function doSomething()
{
var args = doSomething.arguments;
var numArgs = args.length;
for(var i = 0 ; i < numArgs ; i++)
{
console.log("arg " + (i+1) + " = " + args[i]);
//console.log works with firefox + firebug
// you can use an alert to check in other browsers
}
}
doSomething(1, '2', {A:2}, [1,2,3]);
下面是来自AngularJS的代码,它在依赖注入机制中使用了这种技术。
以下是来自http://docs.angularjs.org/tutorial/step_05的解释
Angular的依赖注入器为你的控制器提供服务 当控制器被构造时。依赖注入器 负责创建服务可能的任何传递依赖项 拥有(服务通常依赖于其他服务)。 注意,参数的名称是重要的,因为注入器 使用这些来查找依赖项。
/**
* @ngdoc overview
* @name AUTO
* @description
*
* Implicit module which gets automatically added to each {@link AUTO.$injector $injector}.
*/
var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(.+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function annotate(fn) {
var $inject,
fnText,
argDecl,
last;
if (typeof fn == 'function') {
if (!($inject = fn.$inject)) {
$inject = [];
fnText = fn.toString().replace(STRIP_COMMENTS, '');
argDecl = fnText.match(FN_ARGS);
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
arg.replace(FN_ARG, function(all, underscore, name){
$inject.push(name);
});
});
fn.$inject = $inject;
}
} else if (isArray(fn)) {
last = fn.length - 1;
assertArgFn(fn[last], 'fn')
$inject = fn.slice(0, last);
} else {
assertArgFn(fn, 'fn', true);
}
return $inject;
}
(function(a,b,c){}).toString().replace(/.*\(|\).*/ig,"").split(',')
=> ["a", "b", "c"]
我不知道这个解决方案是否适合您的问题,但它允许您重新定义任何您想要的函数,而无需更改使用它的代码。现有调用将使用定位参数,而函数实现可能使用“命名参数”(单个散列参数)。
我认为你无论如何都会修改现有的函数定义,所以,为什么不拥有一个工厂函数,让你想要的东西:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
var withNamedParams = function(params, lambda) {
return function() {
var named = {};
var max = arguments.length;
for (var i=0; i<max; i++) {
named[params[i]] = arguments[i];
}
return lambda(named);
};
};
var foo = withNamedParams(["a", "b", "c"], function(params) {
for (var param in params) {
alert(param + ": " + params[param]);
}
});
foo(1, 2, 3);
</script>
</head>
<body>
</body>
</html>
希望能有所帮助。
这个包使用重铸来创建AST,然后从它们收集参数名,这允许它支持模式匹配,默认参数,箭头函数和其他ES6特性。
https://www.npmjs.com/package/es-arguments