首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何判断函数是否为空

如何判断函数是否为空
EN

Stack Overflow用户
提问于 2010-12-03 21:53:28
回答 6查看 3.4K关注 0票数 26

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

代码语言:javascript
运行
复制
function foo() {}
function iAmEmpty(a) {
    // yep, empty
}

通过使用toString()和一些正则表达式,通过一些最初的尝试,我已经得到了一些我认为可能行得通的东西。

代码语言:javascript
运行
复制
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

我只是想知道有没有更好的方法?你能看到上面有什么问题吗?

EN

回答 6

Stack Overflow用户

发布于 2010-12-03 22:11:17

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

Kangax曾写过一篇简短的文章:http://perfectionkills.com/those-tricky-functions/

票数 14
EN

Stack Overflow用户

发布于 2017-08-04 04:50:23

箭头函数...

我相信你已经知道,javascript支持arrow functions,它非常简洁,但不幸的是,它不能与你整洁的regex一起工作。

我很快将漂亮的regex转换成了它自己的function,它接受一个function作为输入,并返回它是否为空以便于以后使用。为了演示箭头函数是如何被广泛使用的,我将其放在其中:

代码语言:javascript
运行
复制
isEmpty = f => /^function[^{]+\{\s*\}/m.test(f.toString())

现在,我们可以很容易地测试一个空函数:

代码语言:javascript
运行
复制
function eF() {}

正如我们对isEmpty(eF)所期望的那样,它返回true

再一次使用实际的函数:

代码语言:javascript
运行
复制
function retOne() {return 1;}

同样,与预期的isEmpty(retOne)一样,它返回false

然而,我遇到的问题是箭头函数,所以为了再次初始化一个空的,我们有一个原始的更短的语法:

代码语言:javascript
运行
复制
eF = () => {}

它的'stringified'版本与之前的版本有很大的不同:

代码语言:javascript
运行
复制
"() => {}"

当然,在本例中,当我们需要true时,调用isEmpty(eF)返回false。我不确定你是否需要测试所有函数(例如,包括arrow functions)是否都是空的,但如果你这样做了,你的regex将需要修改……

我自己并不擅长编写它们,但是我已经尝试过几次,而且还有一件事需要考虑,那就是arrow functions的宽松性质,特别是documentation的这一部分

代码语言:javascript
运行
复制
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// equivalent to: (param1, param2, …, paramN) => { return expression; }

// Parentheses are optional when there's only one parameter name:
(singleParam) => { statements }
singleParam => { statements }

这说明了花括号{...}并不总是必需的。所以这个函数:

代码语言:javascript
运行
复制
retOne = () => 1

valid,可能会使形成一个新的regex更加困难。我想到的一个解决方法是使用以下命令从f.toString()中删除所有的花括号:

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

然后在那里使用regex test

如果您希望arrow functions也能够进行测试,希望这是一些有用的考虑因素。

票数 7
EN

Stack Overflow用户

发布于 2017-08-04 03:07:58

您可以尝试的最好方法(因为这很难实现)是添加acornesprima (使用箭头函数too)库并处理JavaScript函数。它会将其标记化,让你解析,这样你就可以根据你的喜好来处理它,检查里面是否真的有零代码,或者只有变量声明而没有任何计算和返回,等等。

实现起来相当简单:

代码语言:javascript
运行
复制
function check(f) {
  console.log("");
  console.log("Checking", f);
  var syntax = esprima.parse(f);
  if (syntax.body.length != 1) {
    console.log("Weird process");
  } else {
    function processBody(body) {
      if (!body || body.length == 0) {
        console.log("Body seems empty. YAY!");
      } else {
        for (var i = 0, command; command = body[i]; i++) {
          if (command.type != "VariableDeclaration") {
            console.log("Body has a", command.type, ", so is not empty.");
            return;
          }
        }
        console.log("Body has only variable declarations, so is empty! (or not, whatever fit your needs)");
      }
    }
    function process(dec) {
      if (dec.type != "FunctionDeclaration") {
        console.log("Weird declaration");
      } else {
        console.log("Function", dec.id.name, "has", dec.params.length, "params");
        processBody(dec.body.body);
      }
    }
    process(syntax.body[0]);
  }
}

check("function hasReturn(arg1, arg2) {var a = arg1 + arg2;return a;}");
check("function hasArgumentsButNoBody(arg1, arg2) {}");
check("function isCompletelyEmptyWithSpacesAndTabsAndLinefeeds() {   \t    \t   \r\n \r\n  }");
check("function hasOnlyVariables() {var a, b = 2; var c = 1 + b;}");
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/esprima/2.7.3/esprima.min.js"></script>

这不会运行函数,只是解析它们,所以使用非安全函数运行是安全的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4346186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档