检查JavaScript函数是否返回而不执行它?

时间:2014-09-09 07:56:59

标签: javascript function return conditional

我有一个给定的函数,除了其他参数之外,还有两个可选参数,它们可能是函数。两者都需要是可选的,一个是函数,一个是布尔值或返回布尔值的函数。

// 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
    }
);

我希望两个函数(以及其他几个参数,如果有关系)都是可选的,这意味着我在函数中有代码来确定用户打算使用哪些参数。

不幸的是,因为两者都可能是函数,并且可能直接在函数调用中指定,所以我不能简单地使用typeofinstanceof条件。但是,由于第一个函数(如果存在)将总是返回一个布尔值(并且第二个函数根本不会返回),我有一个想法是检查它的返回值:

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.
}

这原则上有效;但是,运行typeof BoolOrFunc()会执行该函数,如果函数执行的不仅仅是返回布尔值,则会导致问题:即,如果作为BoolOrFunc传递的函数实际上意味着是SecondFunc。在这种情况下,SecondFunc是一个回调函数,可以执行我不想立即执行的操作,包括DOM修改。

出于这个原因,我的问题是:有没有办法检查函数是否返回而不执行它?

我考虑过的一件事是调用BoolOrFunc.toString(),然后对返回值执行正则表达式搜索,这就像...

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.
}

请注意,上面的代码可能无法正常工作:我实际上并没有为它构建一个测试用例,因为,它看起来非常低效且可能不可靠,我想这里有人可能有一个更优雅的解决方案我的困惑。话虽如此,我想我会把它包括在讨论中。

2 个答案:

答案 0 :(得分:1)

梅沙尔在这个问题上做了一个预测:

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

通过这个预测,该函数不是图灵机,因为我们知道它返回了一些东西。当然,使用简单的RegExp无法做到这一点:只有return !0才会打破这个例子。

但是如果你解析 function.toString()的结果,并且解析器足够智能以找到所有可能的返回点,那么问题应该主要是可以解决的。

答案 1 :(得分:0)

有趣的问题,如果我理解正确的话。首先,我可能会警告不要有这样的开放性论点。我对用例感到好奇。

但是说,这很容易解决你提到的问题(这可能无法完全解决你的问题)。

  

这原则上有效;但是,运行typeof BoolOrFunc()会执行函数...

我认为,这很容易解决。首先,只需检查BoolOrFunc是否为布尔值或函数(仅typeof BoolOrFunc,natch)。如果它是布尔值,我认为我们很好。 SecondFunc缺少undefined)或function - 或者我们处于错误状态。在第一种情况下,这一切都很容易处理。

所以让我们假设第二种情况,我们有BoolOrFunc-As-Function。我们必须执行它,无论它是否真的" BoolOrFunc SecondFunc,因此,在代码的最后一刻,请执行此操作。

这显然是在没有更多伪代码(或生产代码)的情况下变得复杂的地方。如果"可能BoolOrFunc"返回truefalse,您知道您的函数版本为BoolOrFunc。如果它返回undefined,则表示您刚刚调用了SecondFunc。同样,根据您尝试做的事情,您可以在这里进行分支。如果您有truefalse,则必须处理" BoolOrFunc-as-function",否则您已拨打SecondFunc并且可能已完成

这并没有回答更通用的问题,即如何在不调用函数的情况下判断函数是否返回特定类型,但确实解决了此处所示的用例。

但是这个特定的更通用的案例[原文如此]并不太难,只要我们在return中处理真实的,不变的布尔。在这种情况下,regexp路由可行 - 找到所有return\s+.*;并确保每个return后面的内容为truefalse。或者只是比较总return次数与return\s+(false|true);的次数相同。或者其他的东西。并希望函数中的javascript形成良好。真是熊。

如果函数可以返回局部变量(return MightBeBoolean;而不是return true;),那么你几乎要吐司 - 或者如果你接受真实性或虚假性,你就会再次近乎吐司,因为undefined是假的,并且您无法区分BoolOrFuncSecondFunc(这将永远返回" falsey")。这是可能的,但不值得在我能想象的任何合理用例中编写解析器。如果您正在导入lib来执行此操作,那么,谢谢。祝好运。看起来有点过分,因为它的召唤功能稍微有点防守。

我确实想知道,作为参数传递的函数是否都是从Obj.func传递的参数,这会使事情变得更有趣。

有更多真实的代码? ; ^)但最终我建议你不要做任何混乱的论点,只要他们按顺序排列。#34;。我想你可能会做BoolOrFunc / SecondFunc后期评估。否则,我不想这么说,但是在这里再次编码 。