是否有一种方法可以动态地获取函数的函数参数名?
假设我的函数是这样的
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
}
现在,我如何从函数内部获得参数名称及其值的列表到数组中?
当前回答
尝试手动:
function something(arg1, arg2) {
console.log ( arg1 + arg2 );
}
其他回答
(function(a,b,c){}).toString().replace(/.*\(|\).*/ig,"").split(',')
=> ["a", "b", "c"]
您还可以使用“esprima”解析器来避免参数列表中的注释、空格和其他问题。
function getParameters(yourFunction) {
var i,
// safetyValve is necessary, because sole "function () {...}"
// is not a valid syntax
parsed = esprima.parse("safetyValve = " + yourFunction.toString()),
params = parsed.body[0].expression.right.params,
ret = [];
for (i = 0; i < params.length; i += 1) {
// Handle default params. Exe: function defaults(a = 0,b = 2,c = 3){}
if (params[i].type == 'AssignmentPattern') {
ret.push(params[i].left.name)
} else {
ret.push(params[i].name);
}
}
return ret;
}
它甚至可以用这样的代码:
getParameters(function (hello /*, foo ),* /bar* { */,world) {}); // ["hello", "world"]
下面我举个简单的例子:
function test(arg1,arg2){
var funcStr = test.toString()
var leftIndex = funcStr.indexOf('(');
var rightIndex = funcStr.indexOf(')');
var paramStr = funcStr.substr(leftIndex+1,rightIndex-leftIndex-1);
var params = paramStr.split(',');
for(param of params){
console.log(param); // arg1,arg2
}
}
test();
我已经阅读了这里的大部分答案,我想加上我的一句话。
new RegExp('(?:'+Function.name+'\\s*|^)\\((.*?)\\)').exec(Function.toString().replace(/\n/g, ''))[1].replace(/\/\*.*?\*\//g, '').replace(/ /g, '')
or
function getParameters(func) {
return new RegExp('(?:'+func.name+'\\s*|^)\\s*\\((.*?)\\)').exec(func.toString().replace(/\n/g, ''))[1].replace(/\/\*.*?\*\//g, '').replace(/ /g, '');
}
或ECMA6中的单行函数
var getParameters = func => new RegExp('(?:'+func.name+'\\s*|^)\\s*\\((.*?)\\)').exec(func.toString().replace(/\n/g, ''))[1].replace(/\/\*.*?\*\//g, '').replace(/ /g, '');
__
假设有一个函数
function foo(abc, def, ghi, jkl) {
//code
}
下面的代码将返回"abc,def,ghi,jkl"
该代码也将与Camilo Martin给出的一个函数的设置一起工作:
function ( A, b
,c ,d
){}
还有Bubersson对Jack Allan的回答的评论:
function(a /* fooled you)*/,b){}
__
解释
新RegExp (' (?: + Function.name + \ \年代* | ^)\ \ s *\\((.*?)\\)')
这将创建一个正则表达式与新的正则表达式((?:' + Function.name + ' \ \ s * | ^) \ \ s *\\((.*?)\\)').我必须使用新的RegExp,因为我将一个变量(function .name,目标函数的名称)注入到RegExp中。
如果函数名是"foo" (function foo()), RegExp将是/foo\s*\((.*?)\)/。
Function.toString()。替换(\ n / g,”)
然后它将整个函数转换为一个字符串,并删除所有换行符。删除换行符有助于Camilo Martin给出的函数设置。
.exec(…)[1]
这是RegExp.prototype.exec函数。它基本上将正则指数(new RegExp())匹配到字符串(Function.toString())中。然后[1]将返回正则指数((.*?))中找到的第一个捕获组。
.replace (/ \ / \ * . * ?\ \ * / / g,”)。Replace (/ /g, ")
这将删除/*和*/内的所有注释,并删除所有空格。
这现在也支持读取和理解箭头(=>)函数,如f = (a, b) => void 0;,其中function . tostring()将返回(a, b) => void 0,而不是普通函数的函数f(a, b){返回void 0;}。原来的正则表达式会在混乱中抛出一个错误,但现在已经解决了这个问题。
的变化是新的正则表达式(Function.name + \ \年代 *\\((.*?)\\)') (/ 函数\ s *\((.*?)\)/) 新的正则表达式(’(?:+ Function.name + \ \年代 *|^)\\((.*?)\\)') (/(?: 函数\ s *|^)\((.*?)\)/)
如果你想让所有的参数变成一个数组,而不是一个由逗号分隔的字符串,在最后添加.split(',')。
//See this:
// global var, naming bB
var bB = 5;
// Dependency Injection cokntroller
var a = function(str, fn) {
//stringify function body
var fnStr = fn.toString();
// Key: get form args to string
var args = fnStr.match(/function\s*\((.*?)\)/);
//
console.log(args);
// if the form arg is 'bB', then exec it, otherwise, do nothing
for (var i = 0; i < args.length; i++) {
if(args[i] == 'bB') {
fn(bB);
}
}
}
// will do nothing
a('sdfdfdfs,', function(some){
alert(some)
});
// will alert 5
a('sdfdsdsfdfsdfdsf,', function(bB){
alert(bB)
});
// see, this shows you how to get function args in string