[英]Is it possible to send a variable number of arguments to a JavaScript function?
[英]Is it possible to reflect the arguments of a Javascript function?
是否有可能将Javascript函数的所有参数都写入接受? (我知道所有Javascript函数参数都是“可选的”)? 如果没有,是否可以获得参数的数量? 例如,在PHP中,可以使用:
$class = new ReflectionClass('classNameHere');
$methods = $class->getMethods();
foreach ($methods as $method) {
print_r($method->getParameters());
}
...或类似的东西,我有一段时间没有碰过PHP,所以上面的例子可能不正确。
提前致谢!
编辑:不幸的是,我必须能够在函数体外获取参数...对不起澄清,但感谢您当前的答案!
这个新版本也处理胖箭头功能......
args = f => f.toString ().replace (/[\r\n\s]+/g, ' ').
match (/(?:function\s*\w*)?\s*(?:\((.*?)\)|([^\s]+))/).
slice (1,3).
join ('').
split (/\s*,\s*/);
function ftest (a,
b,
c) { }
let aftest = (a,
b,
c) => a + b / c;
console.log ( args (ftest), // = ["a", "b", "c"]
args (aftest), // = ["a", "b", "c"]
args (args) // = ["f"]
);
以下是我认为您正在寻找的内容:
function ftest (a,
b,
c) { }
var args = ftest.toString ().
replace (/[\r\n\s]+/g, ' ').
match (/function\s*\w*\s*\((.*?)\)/)[1].split (/\s*,\s*/);
args将是测试参数名称的数组,即['a','b','c']
如果ftest
是函数,则args将是参数名称的数组。 如果ftest
没有参数,则数组将为空。 如果ftest
未通过正则表达式匹配,则args
的值将为null
,即它不是函数。
有可能获得javascript的所有形式参数名称:
var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function formalParameterList(fn) {
var fnText,argDecl;
var args=[];
fnText = fn.toString().replace(STRIP_COMMENTS, '');
argDecl = fnText.match(FN_ARGS);
var r = argDecl[1].split(FN_ARG_SPLIT);
for(var a in r){
var arg = r[a];
arg.replace(FN_ARG, function(all, underscore, name){
args.push(name);
});
}
return args;
}
这可以通过这种方式测试:
var expect = require('expect.js');
expect( formalParameterList(function() {} )).to.eql([]);
expect( formalParameterList(function () {} )).to.eql([]);
expect( formalParameterList(function /* */ () {} )).to.eql([]);
expect( formalParameterList(function (/* */) {} )).to.eql([]);
expect( formalParameterList(function ( a, b, c ,d /* */, e) {} )).to.eql(['a','b','c','d','e']);
注意:此技术与AngularJs的$ injector一起使用,并在annotate函数中实现。 (见https://github.com/angular/angular.js/blob/master/src/auto/injector.js并在相应的单元测试https://github.com/angular/angular.js/blob/master /auto/injectorSpec.js )
假设你的函数名是foo
是否有可能将Javascript函数的所有参数都写入接受?
arguments[0]
到arguments[foo.length-1]
如果没有,是否可以获得参数的数量?
foo.length
会起作用
只检查所需的字符。 使用func.toString()。正则表达式检查全长。如果函数是500行代码的类...
function getParams(func){
var str=func.toString();
var len = str.indexOf("(");
return str.substr(len+1,str.indexOf(")")-len -1).replace(/ /g,"").split(',')
}
HBP的答案是大多数人都在寻找的,但如果你是定义函数的人,你也可以为函数对象分配一个属性。 例如,
a.arguments = ['foo', 'bar', 'baz']
function a(foo, bar, baz) {
// do stuff
}
这是更清楚的,但你必须写两次你的论点。
现在,当你在函数体外说我只能想象你想知道参数的名称是什么? 因为就值而言,你已经知道你传递了什么参数。 其他答案说你可以得到函数的长度,它是显式声明的参数数量。 现在,如果你想知道函数之外的名字 , toString
hack怎么样?
考虑
function f(oh, hi, there) {
return hi + there / oh;
}
然后
alert(f);
你看到了什么? 直接,只是正则表达出来! 好的,抱歉要提起这件事。 也许它不是标准的ECMAScript,但它,呃,适用于Chrome ....
args = f => f.toString () .replace( /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg,'') .replace(/(\\r\\n\\t|\\n|\\r\\t)/gm,"") .trim() .match (/(?:\\w*?\\s?function\\*?\\s?\\*?\\s*\\w*)?\\s*(?:\\((.*?)\\)|([^\\s]+))/) .slice (1,3) .join ('').replace(/\\s/g, ''). split (/\\s*,\\s*/); /*Test*/ console.log(args((a,b)=>a+b)); console.log(args(function(c,d){return c+d;})); console.log(args(async function(a,b,c){/**/})); console.log(args(function* (a,b,c,d){/**/})); console.log(args(function name(s1,s2){})); console.log(args(function name(/*comment 1*/ s3/*comment2*/,s4// ){})); console.log(args(async function* name(/*comment1*/ s5/*comment2*/,s6){})); console.log(args(async function * name(/*comment1*/ s7/*comment2*/,s8){})); console.log(args(async function *name(/*comment1*/ s9/*comment2*/,s10){}));
JavaScript是ECMAScript的一种方言,根据ECMAScript标准,一个函数也是一个对象,当一个函数被调用时,函数可以访问参数对象,这个参数是类似于数组的对象,它有长度属性,所以你可以使用参数.length遍历传递给此函数的所有参数。 有关详细信息,请访问http://interglacial.com/javascript_spec/a-13.html#a-13.2.1 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.