【问题标题】:Check if JavaScript function returns without executing it?检查 JavaScript 函数是否返回而不执行它?
【发布时间】:2014-09-09 07:56:58
【问题描述】:

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

// 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 传递的函数实际上应该是 @987654328 @。 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.
}

请注意,上面的代码可能不会像写的那样工作:我实际上并没有为它构建一个测试用例,因为,好吧,它看起来效率非常低并且可能不可靠,我认为这里有人可能有一个更优雅的解决方案我的困境。话虽如此,我想我会把它包括在内以供讨论。

【问题讨论】:

  • 顺便说一句,这与图灵机上无法确定的停机问题 (en.wikipedia.org/wiki/Halting_problem) 非常接近。 :)
  • 嘿,你提出了一个很好的观点。我可能对 JS 期望太高了。 :P
  • 对于用户调用提供布尔值的表单和返回布尔值的函数的情况,您是否可以要求他们传入包装在对象中的参数,例如Obj.func(myvar, mystring, myobj, {boolarg: true, funcarg: my_func_that_returns_bool}); 或类似的东西,以明确它是什么。然后用户必须确保my_func_that_returns_bool 做它声称的那样

标签: javascript function return conditional


【解决方案1】:

Meshaal 在问题中做了一个预测:

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

有了这个预测,这个函数就不是图灵机了,因为我们知道它会返回一些东西。当然它不能用一个简单的正则表达式来完成:只是return !0 会破坏这个例子。

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

【讨论】:

    【解决方案2】:

    有趣的问题,如果我理解正确的话。首先,我可能会警告不要有这种开放式的争论。我很好奇用例。

    但话虽如此,解决您提到的问题很容易(这可能无法完全解决您的问题)。

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

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

    让我们假设第二种情况,我们有BoolOrFunc-As-Function。我们将不得不执行它,无论它是“真的”BoolOrFunc SecondFunc,所以,在你的代码的最后时刻,执行它。

    如果没有您提供更多的伪代码(或生产代码),这显然是事情变得复杂的地方。如果“可能的BoolOrFunc”返回truefalse,你就知道你有一个BoolOrFunc 的函数版本。如果它返回undefined,你知道你刚刚调用了SecondFunc。同样,根据您要执行的操作,您可以在此处分支。如果您有 truefalse,则必须处理“BoolOrFunc-as-function”,否则您已调用 SecondFunc 并且可能已完成。

    这并不能回答更通用的问题,即如何判断函数是否返回特定类型而不调用它,但确实解决了此处介绍的用例。

    但是,只要我们在returns 中处理真正的、常量布尔值,这个更具体的更通用的情况 [原文如此] 并不太难。在这种情况下,正则表达式路径会起作用——找到所有return\s+.*; 并确保每个return 后面是truefalse。或者只是比较return 的总数与return\s+(false|true); 的总数相同。或者其他的东西。并希望函数中的javascript格式正确。真是一只熊。

    如果函数可以返回局部变量(return MightBeBoolean; 而不是return true;),那么您就差一点了——或者如果您接受真假,那么您又差一点就差一点了,因为undefined 是假的,而且您无法区分BoolOrFuncSecondFunc(它总是会返回“falsey”)。这是可能的,但几乎不值得在我能想象的任何合理用例中编写解析器。如果你要导入一个库来做到这一点,哎呀。祝你好运。具有在调用中更具防御性的功能似乎有点矫枉过正。

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

    有更多真实的代码吗? ;^) 但最终我建议你不要做“传递任何混乱的论点,只要它们是有序的”。我认为您可能会进行 BoolOrFunc/SecondFunc 后期评估。否则,我不想这么说,但在这里写更多的代码of

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多