Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.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_Reflection - Fatal编程技术网

Javascript 如何确定函数是否为空

Javascript 如何确定函数是否为空,javascript,reflection,Javascript,Reflection,我希望能够检查给定函数是否为空。也就是说,它的身体里没有任何东西,例如: function foo() {} function iAmEmpty(a) { // yep, empty } 通过使用toString()和一些正则表达式,我得到了一些我认为还可以的东西 function foo(a, b, c) {} /^function[^{]+\{\s*\}/m.test(foo.toString()); // true function bar(a, b, c) { var d

我希望能够检查给定函数是否为空。也就是说,它的身体里没有任何东西,例如:

function foo() {}
function iAmEmpty(a) {
    // yep, empty
}
通过使用
toString()
和一些正则表达式,我得到了一些我认为还可以的东西

function foo(a, b, c) {}

/^function[^{]+\{\s*\}/m.test(foo.toString());  // true

function bar(a, b, c) { var d; }

/^function[^{]+\{\s*\}/m.test(bar.toString());  // false

我只是想知道是否有更好的方法?您可以看到上面的内容有什么问题吗?

这是不可取的。没有标准可以精确地确定函数的
toString()
方法应该返回什么,因此,即使您在当前的浏览器中实现了这一点,未来的浏览器也可能有理由更改其实现并破坏您的代码


Kangax对此做了简要的描述:

我不认为这有什么用处,但是您可以通过将模式锚定到字符串的端来简化它

  /[^{\s]\s*\}$/.test(String(bar))

您可以尝试的最好方法是添加或(也使用箭头函数)库,并处理JavaScript函数,以适应最大的可能性(因为这很难实现)。它将标记化它以供您解析,因此您可以根据自己的喜好对其进行处理,检查内部是否实际上没有代码,或者是否只有没有任何计算或返回的变量声明,等等

实现起来非常简单:

功能检查(f){
控制台日志(“”);
控制台日志(“检查”,f);
var syntax=esprima.parse(f);
if(syntax.body.length!=1){
日志(“奇怪的过程”);
}否则{
函数processBody(body){
如果(!body | | body.length==0){
log(“身体似乎是空的,耶!”);
}否则{
for(var i=0,command;command=body[i];i++){
if(command.type!=“VariableDeclaration”){
log(“Body有一个”,command.type,”,所以不是空的。”);
返回;
}
}
log(“Body只有变量声明,所以是空的!(或者不是,只要适合您的需要)”;
}
}
功能过程(dec){
if(dec.type!=“函数声明”){
console.log(“怪异声明”);
}否则{
log(“函数”,dec.id.name,“has”,dec.params.length,“params”);
进程体(dec.body.body);
}
}
进程(syntax.body[0]);
}
}
检查(“函数hasrurn(arg1,arg2){var a=arg1+arg2;返回a;}”);
检查(“函数hasArgumentsButNoBody(arg1,arg2){}”);
检查(“函数完全为空,带有空格和tabsandlinefeeds(){\t\t\r\n\r\n}”);
检查(“函数hasOnlyVariables(){var a,b=2;var c=1+b;}”)
箭头函数。。。 我相信您一定知道,
javascript
支持非常简洁的代码,但不幸的是,它不能与您的整洁的
regex
配合使用

我很快将您的nice
regex
转换为自己的
函数
,它将
函数
作为输入,并返回它是否为空,以方便以后使用。为了演示如何广泛使用箭头函数,我将其放在一个示例中:

isEmpty = f => /^function[^{]+\{\s*\}/m.test(f.toString())
现在,我们可以轻松地测试一个空函数:

function eF() {}
function retOne() {return 1;}
retOne = () => 1
正如我们所期望的那样,
isEmpty(eF)
返回
true

还有一个实际的功能:

function eF() {}
function retOne() {return 1;}
retOne = () => 1
与预期的一样,
isEmpty(retOne)
返回
false

但是,我遇到的问题是箭头函数,因此要再次初始化空函数,我们使用了较短的原始语法:

eF = () => {}
它的
“stringified”
版本与之前的版本有很大不同:

"() => {}"
当然,在这种情况下,调用
isEmpty(eF)
会在需要
true
时返回
false
。我不确定您是否需要测试所有函数(即,包括
箭头函数
)是否为空,但如果需要,您的
正则表达式
将需要修改

<>我自己写的不是很好,但是已经尝试了一对又一件事情,你可能要考虑的是<代码>箭头函数< /代码>的宽泛性。 这说明了花括号
{…}
并非总是必要的。所以这个函数:

function eF() {}
function retOne() {return 1;}
retOne = () => 1
是有效的
,并且可能使生成新的
正则表达式变得更加困难。我想到的一个解决方法是使用以下方法删除
f.toString()
中的所有花括号:

str.replace(/[{}]/g',)

然后在那里使用
regex测试


希望这是一个有帮助的事情,如果你想让代码>箭头函数< /代码>也能被测试。

< P>它很简单,只需检查函数中包含的函数,然后检查它是否是空的。 检查此项
以下是完整的工作代码:

function foo(a, b, c) {}

function bar(a, b, c) {
  var d;
}

function isEmpty(value) {
  return (value == null || value.length === 0);
}

function check(test) {
  var entire = test.toString();
  var body = entire.slice(entire.indexOf("{") + 1, entire.lastIndexOf("}"));
  return body;

}
console.log(isEmpty(check(foo)), isEmpty(check(bar))); //return true false

JS反射的概念让我很开心,但是关于这个问题;您已经处理了空格和多行,所以afaik这是最好的。不要忘记查找所有注释的方法体(如果这是您的规范),我认为这样做是一个好方法。@Brad,注释会自动从toString()的输出中删除,afaik。重复:谢谢链接!我没有意识到浏览器实现的差异如此之大。@Tim ES5:ES6@ManasJayanth:关键词是“精确”。这两个规范都说返回了函数的“依赖于实现的表示”。哦,对了。我的坏:)但在Mac上运行几个简单的函数
toString
s似乎可以在不同浏览器(FF、Safari和Chrome)上返回一致的结果,即非本机函数。如果该函数重写toString方法,则此操作无效。@AlexisTyler检查plunker@AlexisTyler在你的问题中提到了重写,如果你想重写它,你可以将默认的toString函数保存在另一个函数中