Check if JavaScript function returns without executing it?

I have a given function that, among other arguments, takes two optional arguments, which can be functions. Both must be optional, one of them will be a function, and one will be either a logical or a function that returns a logical value.

// Obj.func(variable, String[, Object][, Boolean||Function][, Function]); Obj.func = function(other, assorted, args, BoolOrFunc, SecondFunc) { // execution }; Obj.func( [ 'some', 'data' ], 'of varying types', { and: 'some optional arguments' }, function() { if(some condition) { return true; } return false; }, function() { // do things without returning } ); 

I want both functions (and a few other arguments, if that matters) to be optional, which means that I have code in the function to determine which arguments the user should use.

Unfortunately, since both can be functions and can be specified directly in a function call, I cannot just use typeof or instanceof conventions. However, since the first function, if it exists, will always return a boolean value (and the second function will not return at all), one of my ideas would be to check its return value:

 if(typeof BoolOrFunc === 'boolean' || (typeof BoolOrFunc === 'function' && typeof BoolOrFunc() === 'boolean')) { // BoolOrFunc is either a boolean or a function that returns a boolean. // Handle it as the intended argument. } else { // Otherwise, assume value passed as BoolOrFunc is actually SecondFunc, // and BoolOrFunc is undefined. } 

It works in principle; however, executing typeof BoolOrFunc() executes the function, which causes a problem if the function does more than just return a boolean value: that is, if the function passed as BoolOrFunc actually means SecondFunc . SecondFunc , in this case, is something like a callback function and can perform actions, including changes to the DOM, which I do not want to execute immediately.

For this reason, my question is: Is there a way to check if a function returns without executing it?

One thing I was considering was calling BoolOrFunc.toString() , then do a regular expression search for the return value, something like strings ...

 if(typeof BoolOrFunc === 'boolean' || (typeof BoolOrFunc === 'function' && BoolOrFunc.toString().search(/return (true|false);/) !== -1)) { // BoolOrFunc is either a boolean or contains a return string with a boolean. // Handle it as the intended argument. } 

Please note that the above code may not work as it is written: I actually did not build a test case for it, because it seems to look extremely inefficient and potentially unreliable, and I decided that someone here might being a more elegant solution is my embarrassment. After I said, I decided to include it for discussion purposes.

+5
source share
2 answers

Meshaal made a prediction in a question:

 "... one will either be a boolean or a function that returns a boolean." "... first function, if it exists, will always return a boolean." 

With this prediction, a function is not a Turing machine, because we know that it returns something. Of course, this cannot be done with simple RegExp: just return !0 will break the example.

But if you analyze the result of the .toString () function, when the parser is smart enough to find all possible return points, the problem should be solved mainly.

+1
source

An interesting question, if I understand correctly. First, I would probably caution against such open arguments. I am curious how to use a use case.

But that says it's easy enough to get around the problems you are talking about (which may not completely solve your problem).

It works in principle; however, running typeof BoolOrFunc () performs the function ...

This is easy enough to fix, I think. First, just check if BoolOrFunc boolean or function (just typeof BoolOrFunc , natch). If it is logical, I assume that everything is in order. Either SecondFunc missing ( undefined ), or function - or we are in an error state. All this is easy to handle in this first case.

So, suppose the second case that we have a BoolOrFunc-As-Function . We have to execute it, whether it is " BoolOrFunc " or SecondFunc , so at the last moment, maybe in your code, do it.

This, obviously, is that things get complicated without using pseudo-code (or production code). If "possible BoolOrFunc " returns true or false , you know that you have a functional version of BoolOrFunc . If it returns undefined , you know that you just called SecondFunc . Again, depending on what you are trying to do, you go here. If you have true or false , you need to handle the "BoolOrFunc-as-function", otherwise you called SecondFunc and most likely did.

This does not answer the more general question of how to determine if a function returns a particular type without calling it, but solves your use case, as shown here.

But this particular more general case [sic] is not too complicated if we are dealing with real, constant Booleans in return s. In this case, the regexp route will work - find all return\s+.*; and make sure each return is true or false . Or just compare the return counter to the same as return\s+(false|true); . Or something. And I hope that the javascript in the function will be well formed. What a bear already.

If a function can return local variables ( return MightBeBoolean; rather than return true; ), you are almost toasts - or if you accept truthfulness or falsehood, you start the toast again, since undefined is false, and you cannot tell the difference between BoolOrFunc or SecondFunc (which would always return falsey). Perhaps, but you should not write a parser in any reasonable case, I can imagine. And if you import lib for this, let's. Good luck. Overkill seems to have a function that is slightly more secure in its call.

I am wondering if both functions passed as arguments are passed from the arguments of Obj.func , which will make things even more interesting.

Got a more real code ?; ^) But in the end, I recommend that you do not "skip any clutter of arguments while they are in order." I think you can probably evaluate BoolOrFunc / SecondFunc. Otherwise, I hate talking about it, but here is a little more of .

0
source

Source: https://habr.com/ru/post/1202132/


All Articles