Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获取用于接口的函数参数名称_Javascript - Fatal编程技术网

Javascript 获取用于接口的函数参数名称

Javascript 获取用于接口的函数参数名称,javascript,Javascript,有人能帮我检索函数参数名吗?例如: var A = function(a, b, c) {}; 我需要获取函数外部的参数名,即a、b和c(如字面上的字符串,例如放入数组[“a”、“b”、“c”),这样我不仅可以验证类中面向接口的对象/类属性,还有参数 在这个问题开始引起混淆之前,让我解释一下我的术语中的接口实现,以及我需要回答上述问题的原因: 首先,我发现了一种有趣的方法,我想用JavaScript实现Glen Ford的界面: for (var member in theInterface

有人能帮我检索函数参数名吗?例如:

var A = function(a, b, c) {};
我需要获取函数外部的参数名,即abc(如字面上的字符串,例如放入数组[“a”、“b”、“c”),这样我不仅可以验证类中面向接口的对象/类属性,还有参数


在这个问题开始引起混淆之前,让我解释一下我的术语中的接口实现,以及我需要回答上述问题的原因:

首先,我发现了一种有趣的方法,我想用JavaScript实现Glen Ford的界面:

for (var member in theInterface) {
    if ( (typeof theObject[member] != typeof theInterface[member]) ) {
        alert("object failed to implement interface member " + member);
        return false;
    }
}
(有关实施的详细信息,请参见)

但是,上面的实现只验证对象属性(变量和方法),这对我来说还不够

我需要对参数级别进行更多验证,以便实现一个接口的代码应该遵循接口方法,也应该遵循接口方法中的参数



请不要争论为什么要使用界面,或者为什么它是无用或有用的;相反,如果您能够提供更好的接口实现,它将非常有用。这里的重点是我只需要知道如何获取函数参数名。

我怀疑是否有合适的方法来实现这一点,在javascript中,参数值在传递时可以是不同的类型,类型并不重要,但顺序如此

这可能不是你想要的答案,但这至少有帮助

function test(a,b,c,d) {

}

//this will give us the number of parameters defined in the a function.
confirm(test.length); 
要真正了解名称,可以解析函数定义

  var str = window['test'].toString();
   //str will be "function test(a,b,c,d){}"
下面是我做的一个简单的解析测试:

function test(a,b,c,d)
{

}

var b = function(x,y,  z){};
alert(getFnParamNames(b).join(","));
alert(getFnParamNames(test).join(","));

function getFnParamNames(fn){
    var fstr = fn.toString();
    return fstr.match(/\(.*?\)/)[0].replace(/[()]/gi,'').replace(/\s/gi,'').split(',');
}

唯一的方法是将函数作为字符串检索,并使用
RegExp
获取参数名称:

function test(a,b,c){/*function body*/}
//=> this should return 'a,b,c':
test.toString().replace(/(function.+\()(.+(?=\)))(.+$)/,'$2');

您可以使用中描述的正则表达式,另一种选择是使用标记器。以下代码使用
acorn
javascript解析器检查函数是否包含特定的参数名:

function isFunction(value) {
  return value && typeof value === 'function';
}

function hasArgument(func, name) {

if (!isFunction(func) || !name) {
    return false;
}

var tokenizer = acorn.tokenize(func);
var token = tokenizer();

while (token.type.type !== 'eof') {

    // ')' closes function, we do not want to look inside the function body
    if (token.type.type === ')') {
        return false;
    }

    if (token.type.type === 'name' && token.value === name) {
        return true;
    }

    token = tokenizer();

}

return false;

}

为了完成@jerjer的回答,我们还可以确保至少有一个匹配项:

function getFnParamNames(fn){
  const match = fn.toString().match(/\(.*?\)/) 
  return match ? match[0].replace(/[()]/gi,'').replace(/\s/gi,'').split(',') : [];
}

现在是2018年,我可以添加一个支持箭头功能的解决方案吗

/**
 *  (Function) => String[]
 */
function getFnParamNames(fn){
    const fnStr = fn.toString()
    const arrowMatch = fnStr.match(/\(?[^]*?\)?\s*=>/) 
    if (arrowMatch) return arrowMatch[0].replace(/[()\s]/gi,'').replace('=>','').split(',')
    const match = fnStr.match(/\([^]*?\)/) 
    return match ? match[0].replace(/[()\s]/gi,'').split(',') : []
}
注:

[^]
匹配所有类型的字符,包括新行(而
不包括新行)。来源

*?
非贪婪量词。更多解释

测试案例:

console.log(getFnParamNames(name => {
}))

console.log(getFnParamNames(name=>{
}))

console.log(getFnParamNames((name) => {
}))

console.log(getFnParamNames((name, age, ...args) => {
}))

console.log(getFnParamNames((name,age,...args)=>{
}))

console.log(getFnParamNames(function(name,age,...args){
}))

console.log(getFnParamNames(function (name , age , ...args ) {
}))

console.log(getFnParamNames(function(
    name,
    age,
    ...args){
}))

console.log(getFnParamNames(new Function('name', 'age' , '...args', 'console.log(args.length)' )))

这是一个不清楚的问题。。。什么是“参数名”?您已经将函数的参数声明为“a”、“b”和“c”。。。你能澄清一下吗?还有,你说的“验证”是什么意思?您只是在寻找在多个类中验证传入参数的方法吗?如果是这样的话,我的第一个倾向是创建一个超类或其他东西来对所有子类进行验证…基本上,JavaScript不是类型安全的-但听起来这就是你想要的?嗨,Jesse,是的,我已经在函数中声明了我的参数a、b和c。但是我需要得到它们(比如,字面上把它们当作字符串,比如[“a”、“b”、“c”),这样我就可以在进一步的接口实现中使用这些名称。我需要“验证”我的对象属性与接口对象属性相同。如果您在我提供的链接中尝试过接口实现,也许您会明白我的意思。在链接中,它只对接口成员“验证”对象成员,但是,我需要更深入的验证,这也对接口成员的参数进行验证。可能重复:感谢jerjer,我认为这是对将函数解析为字符串的投票。是的,我认为toString()将是确定参数名称的唯一方法。然后使用一个简单的正则表达式应该允许您将它们映射到对象属性@Arly,请查看测试函数的更新答案,以解析参数namesHi jerjer,很高兴您更新了更好的答案。我已经对它进行了测试,看起来您也在修剪字符串,这样就不会保存由函数声明(两种样式)引起的任何空格,如果有人看到这一点,这将非常有用。美好的谢谢它就像一个符咒,就像我在解析字符串时需要的一样。嗨,阿莉,很高兴我能帮上忙。如果您不想使用
$2
(已弃用),则可选择
test.toString().match(/(function.+\()(.+(?=\))(.+$)/)[2]。快乐编码!