双重函数调用还是将结果存储为变量?

4

假设我有一个在其他地方定义的函数f(-)。我在下面的代码中使用它两次:

if (f(-) satisfies some condition) {
    do some stuff
    if (f(-) satisfies some other condition) {
        do some other stuff
    }
}

当代码运行时,f(-)会被计算两次吗?或者解释器是否“智能”地看到只需要计算一次?如果是这样,是否建议在该代码之前定义一个常量x = f(-)并使用它代替f(-)?我通常会这样做,但我不确定是否有必要,特别是当f(-)可以非常快速地计算出来时。
如果有影响的话,这种语言是JavaScript。

该函数在您的示例中应被调用两次,除非您在代码外部调用并分配函数结果,然后稍后多次使用IF进行测试。 - Mohsen Alyafei
如果您知道该函数两次返回相同的值,应将其移至常量。否则,它将被评估两次。我提供了一个描述作为答案,以帮助其他读者。好问题。 - Keet Sugathadasa
4个回答

1
如果 f(-) 满足其他条件,它将调用相同的函数,并且可能永远不会进入此 if 后面的块,因为该函数满足外部的 if 条件,从而进入该块。
创建一个常量,并根据该值执行下一步操作。
const isFunResult = f(-);
// expecting this function gives a boolean
   

if(isFunResult){
     // code goes here
    }
   else{
    // code goes here
   }

如果函数返回多个结果,您还可以使用switch语句。

谢谢。您能具体说明如果f(-)计算两次,那么(如果两个条件都满足的话)会发生什么吗? - user11909477

0

运行此代码以查看示例。即使条件相同。

function test_me() {
 console.log("I got called");
    return 99;
}
                        
if (test_me() == 99) console.log("n=99");  // 1st function call
if (test_me() == 99) console.log("n=99");  // 2nd function call

// is different from the following

var n = test_me();                    // function called once
if (n == 99) console.log("n=99");     // 1st test
if (n == 99) console.log("n=99");     // 1st test


0
简单来说,解释器不够“智能”,无法看到只需计算一次即可。因此它会调用函数两次。
你需要的是一种叫做记忆化的东西,它用于优化计算密集型函数的性能,以便在传递相同参数时进行记忆。
如果你需要记忆化,你可以在自己的函数中实现它,或者你可以使用支持它的 JavaScript 框架。比如 React 有 useMemo 钩子。
请参见 https://reactjs.org/docs/hooks-reference.html#usememo 通常情况下,你不需要这样做,只需将函数的结果存储在变量中就足够了。

0

回答你的问题:是的,它会计算函数f(-)两次。

更重要的是程序员的意图,而不是解释器的智能。如果程序员认为函数第二次调用可能返回一个不同的值,那么同一个函数可以被调用两次。例如:如果函数内部使用了new Date()...

但是,如果程序员知道两次输出结果相同(就像你的情况),最好定义一个常量x = f(-)并重复使用它。这将提高性能(如果函数很重)并改善代码可维护性。

即使是编译器,除非函数是非常简单的代码,否则编译器可能无法智能地检测到这一点。但正如@perellorodrigo所提到的,您可以使用memoization,但这超出了本答案的范围。

总之,如果您调用同一个函数两次,它将被评估两次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接