I want to be able to check whether a given function is empty or not. That is, there is nothing in its body, eg:
function foo() {}
function iAmEmpty(a) {
// yep, empty
}
With some initial playing around, I've got something which I think might be ok, by using toString()
and some regexes.
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
I was just wondering if there was a better approach? Are there any problems with the above you can see?
I don't see the use for this, but you could make it simpler by anchoring the pattern to the end of the string.
This isn't advisable. There is no standard determining precisely what a function's
toString()
method should return, so even if you get this working in current browsers, future browsers may justifiably change their implementation and break your code.Kangax has written briefly about this: http://perfectionkills.com/those-tricky-functions/
The best thing you can try, to fit the maximum possibilities (as this is pretty hard to achieve), is to add acorn or esprima (works with arrow functions too) libraries and process the JavaScript function. It will tokenize it for you to parse, so you can process it to your likings, checking if there's actually zero code inside, or there's only variable declarations without any calculation nor return, etc...
Is pretty straightforward to implement:
This will not run the functions, just parse them, so is safe to run with non-secure functions.
It's simple just check the function contain and then check the contain if it's empty or not .
check this Plunker
here's full working code:
Arrow functions...
As I am sure you are aware,
javascript
supports arrow functions which are really succinct but unfortunately don't work with your neatregex
.I quickly converted your nice
regex
into its ownfunction
which takes afunction
as an input and returns whether or not it is empty for simplicity later. Just to demonstrate how arrow functions can be widely used, I put it in one:Now, we can easily test an empty function:
which as we would expect with
isEmpty(eF)
returnstrue
.And once more with an actual function:
which again as expected with
isEmpty(retOne)
returnsfalse
.However, the issue I encountered was with arrow functions so to initialize an empty one again, we have a shorter syntax of the original:
and the
'stringified'
version of that is quite different to the one before:so of course in this case the call
isEmpty(eF)
returnsfalse
when we wanttrue
. I'm not sure if you require to test if all functions (i.e. includingarrow functions
) are empty but if you do, yourregex
will need modifying...I am not great at writing them myself, but have attempted a couple and one further thing that you might want to consider is the lenient nature of the
arrow functions
especially this part of the documentation:which shows how the curly brackets
{...}
are not always necessary. So this function:is
valid
and could make forming a newregex
more difficult. One workaround I thought of is to just remove all curly brackets fromf.toString()
using:str.replace(/[{}]/g, '')
.and then work with a
regex test
from there.Hopefully this is something helpful to consider if you want
arrow functions
to also be able to be tested.