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)) {
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.