如何确定函数是否为空

nic*_*ckf 25 javascript reflection

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

function foo() {}
function iAmEmpty(a) {
    // yep, empty
}
Run Code Online (Sandbox Code Playgroud)

通过一些初步的游戏,我有一些我认为可能没问题的东西,通过使用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
Run Code Online (Sandbox Code Playgroud)

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

Tim*_*own 14

这是不可取的.没有标准确定函数的toString()方法应该返回什么,所以即使你在当前的浏览器中使用它,未来的浏览器也可以合理地改变它们的实现并破坏你的代码.

Kangax简要地写了这个:http://perfectionkills.com/those-tricky-functions/


Joe*_*don 6

箭头功能......

我相信你知道,javascript支持箭头功能,这些功能非常简洁,但遗憾的是不适用于你的整洁regex.

我很快将你的nice regex转换为它自己的nice function,它接受一个function输入并返回它是否为空以简化以后.为了演示箭头函数如何被广泛使用,我把它放在一个:

isEmpty = f => /^function[^{]+\{\s*\}/m.test(f.toString())
Run Code Online (Sandbox Code Playgroud)

现在,我们可以轻松测试一个空函数:

function eF() {}
Run Code Online (Sandbox Code Playgroud)

正如我们将与期望isEmpty(eF)的回报true.

再一次具有实际功能:

function retOne() {return 1;}
Run Code Online (Sandbox Code Playgroud)

再次与预期的isEmpty(retOne)回报false.

但是,我遇到的问题是使用箭头函数,所以再次初始化一个空函数,我们有一个较短的原始语法:

eF = () => {}
Run Code Online (Sandbox Code Playgroud)

它的'stringified'版本与之前的版本完全不同:

"() => {}"
Run Code Online (Sandbox Code Playgroud)

所以当然在这种情况下,当我们想要时,调用会isEmpty(eF)返回.我不确定你是否需要测试所有功能(包括)是否为空,但如果你这样做,你 需要修改......falsetruearrow functionsregex

我自己写的并不是很擅长,但是你可能想要考虑的另外一件事是arrow functions特别是这部分文档的宽松本质:

(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 }
Run Code Online (Sandbox Code Playgroud)

这表明大括号{...}并不总是必要的.所以这个功能:

retOne = () => 1
Run Code Online (Sandbox Code Playgroud)

是,valid并且可能使新的形成regex更加困难.我想到的一个解决方法是从f.toString()使用中删除所有大括号:

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

然后regex test从那里工作.

希望如果您想要arrow functions也能够进行测试,这有助于考虑.