简体   繁体   English

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

[英]Is it possible to reflect the arguments of a Javascript function?

Is it possible to get all of the arguments a Javascript function is written to accept? 是否有可能将Javascript函数的所有参数都写入接受? (I know that all Javascript function arguments are "optional")? (我知道所有Javascript函数参数都是“可选的”)? If not, is it possible to get the number of arguments? 如果没有,是否可以获得参数的数量? For example, in PHP, one could use: 例如,在PHP中,可以使用:

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

... or something like that, I haven't touched PHP in a while so the example above may not be correct. ...或类似的东西,我有一段时间没有碰过PHP,所以上面的例子可能不正确。

Thanks in advance! 提前致谢!

EDIT: Unfortunately, I have to be able to get the arguments outside of the body of the function... Sorry for the lack of clarification, but thanks for the current answers! 编辑:不幸的是,我必须能够在函数体外获取参数...对不起澄清,但感谢您当前的答案!

This new version handles fat arrow functions as well... 这个新版本也处理胖箭头功能......

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"]
             );

Here is what I think you are looking for : 以下是我认为您正在寻找的内容:

 function ftest (a,
                 b,
                 c) { }
 var args = ftest.toString ().
              replace (/[\r\n\s]+/g, ' ').
              match (/function\s*\w*\s*\((.*?)\)/)[1].split (/\s*,\s*/);

args will be an array of the names of the arguments of test ie ['a', 'b', 'c'] args将是测试参数名称的数组,即['a','b','c']

The value is args will be an array of the parameter names if the ftest is a function. 如果ftest是函数,则args将是参数名称的数组。 The array will be empty if ftest has not parameters. 如果ftest没有参数,则数组将为空。 The value of args will be null if ftest fails the regular expression match, ie it is not a function. 如果ftest未通过正则表达式匹配,则args的值将为null ,即它不是函数。

it is possible get all the formal parameter name of a javascript: 有可能获得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;
 }

this can be tested this way : 这可以通过这种方式测试:

 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']);

Note: This technique is use with the $injector of AngularJs and implemented in the annotate function. 注意:此技术与AngularJs的$ injector一起使用,并在annotate函数中实现。 (see https://github.com/angular/angular.js/blob/master/src/auto/injector.js and the corresponding unit test in https://github.com/angular/angular.js/blob/master/auto/injectorSpec.js ) (见https://github.com/angular/angular.js/blob/master/src/auto/injector.js并在相应的单元测试https://github.com/angular/angular.js/blob/master /auto/injectorSpec.js

Suppose your function name is foo 假设你的函数名是foo

Is it possible to get all of the arguments a Javascript function is written to accept? 是否有可能将Javascript函数的所有参数都写入接受?

arguments[0] to arguments[foo.length-1] arguments[0]arguments[foo.length-1]

If not, is it possible to get the number of arguments? 如果没有,是否可以获得参数的数量?

foo.length would work foo.length会起作用

check only required chars. 只检查所需的字符。 with func.toString().regex you checked full length.so if function is class with 500 lines of code... 使用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's answer is what most people are looking for, but if you're the one defining the function, you can also assign a property to the function object. HBP的答案是大多数人都在寻找的,但如果你是定义函数的人,你也可以为函数对象分配一个属性。 For example, 例如,

a.arguments = ['foo', 'bar', 'baz']
function a(foo, bar, baz) {
  // do stuff
}

This is debatably more clear, but you'll have to write your arguments twice. 这是更清楚的,但你必须写两次你的论点。

Now when you say outside the body of the function I can only imagine that you want to know what the names of the parameters are? 现在,当你在函数体外说我只能想象你想知道参数的名称是什么? Because as far as the values go, you already know what arguments you are passing. 因为就值而言,你已经知道你传递了什么参数。 Other answers have said you can get the length of the function, which is the number of parameters it explicitly declares. 其他答案说你可以得到函数的长度,它是显式声明的参数数量。 Now if you want to know the names outside the function, how about the toString hack? 现在,如果你想知道函数之外的名字toString hack怎么样?

Consider 考虑

function f(oh, hi, there) {
    return hi + there / oh;
}

Then 然后

alert(f);

What do you see? 你看到了什么? RIght, just regex them out! 直接,只是正则表达出来! Okay, SORRY to bring this up. 好的,抱歉要提起这件事。 Perhaps it is not standard ECMAScript, but it, uh, works in Chrome.... 也许它不是标准的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 is a dialects of ECMAScript, according to ECMAScript standard, a function is also a object, and when a function is called, function can access arguments object, this arguments is array-like object, it has length property, so you can use arguments.length to traverse all arguments passed to this function. JavaScript是ECMAScript的一种方言,根据ECMAScript标准,一个函数也是一个对象,当一个函数被调用时,函数可以访问参数对象,这个参数是类似于数组的对象,它有长度属性,所以你可以使用参数.length遍历传递给此函数的所有参数。 visit http://interglacial.com/javascript_spec/a-13.html#a-13.2.1 for more details. 有关详细信息,请访问http://interglacial.com/javascript_spec/a-13.html#a-13.2.1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM