是否有可能反映Javascript函数的参数?



是否有可能获得Javascript函数写入接受的所有参数?(我知道所有Javascript函数参数都是"可选的")?如果不是,是否有可能得到参数的数量?例如,在PHP中,可以使用:

$class = new ReflectionClass('classNameHere');
$methods = $class->getMethods();
foreach ($methods as $method) {
    print_r($method->getParameters());
}

…我有一段时间没有接触PHP了,所以上面的例子可能不正确。

提前感谢!

编辑:不幸的是,我必须能够在函数体的之外获得参数…很抱歉没有澄清,但感谢你现在的回答!

这个新版本也可以处理胖箭头函数…

args = f => f.toString ().replace (/[rns]+/g, ' ').
              match (/(?:functions*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 (/[rns]+/g, ' ').
              match (/functions*w*s*((.*?))/)[1].split (/s*,s*/);

args将是test的参数名称的数组,即['a', 'b', 'c']

如果ftest是函数,则值是args将是参数名称的数组。如果ftest没有参数,则该数组为空。"args"的值为"null"如果ftest不能匹配正则表达式,即它不是一个函数

可以获得javascript的所有形式参数名:

var FN_ARGS = /^functions*[^(]*(s*([^)]*))/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^s*(_?)(S+?)1s*$/;
var STRIP_COMMENTS = /((//.*$)|(/*[sS]*?*/))/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] to 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如何?

考虑
function f(oh, hi, there) {
    return hi + there / oh;
}
然后

alert(f);

你看到了什么?对,把它们正则化!好吧,很抱歉提起这件事。也许它不是标准的ECMAScript,但它,嗯,在Chrome中工作....

args = f => f.toString ()
    .replace( /((//.*$)|(/*[sS]*?*/))/mg,'')
    .replace(/(rnt|n|rt)/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标准,函数也是一个对象,当调用函数时,函数可以访问参数对象,这个参数是类数组对象,它有长度属性,所以你可以使用参数。遍历传递给此函数的所有参数的长度。详情请访问http://interglacial.com/javascript_spec/a-13.html#a-13.2.1

相关内容

  • 没有找到相关文章

最新更新