Javascript 嵌套函数求值

Javascript Nested Function Evaluation

嗨,我对这个 Javascript 函数感到困惑:

var currying = function(a) {
    return function(b){
        return function(c){
            return function(d){
                return a + b /c * d;
                };
            };
        };
    };
var a = currying(4)(8);
var b = a(2)(6);
console.log(b);

它输出 28,但我不确定 Javascript 是如何评估该函数的。我还了解到 a = 4、b = 8、c = 2 最后是 d = 6。感谢有人能够解释该功能。

这是一种叫做闭包

的词法范围

基本上:闭包是函数中的函数,可以访问所有父变量和参数。由于 javascript 中的每个参数默认情况下都是通过引用传递的,它甚至可以修改父变量,以便您稍后可以执行父函数来查看更改。最好的例子是 jquery 的 ready 函数,它包含所有其他函数。

您可以在此处阅读更多相关信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

这是一个非常复杂的 currying 示例 - 因此是主要函数的名称。

柯里化起源于函数式编程领域,要完全理解它,我建议您阅读一些内容,尤其是它在 javascript.

中的实现

给大家一些指点:

行中:

var a = currying(4)(8);

调用第一个函数,参数为4;该函数调用的结果是另一个函数,然后使用参数 8.

立即调用该函数

最终,所有发生的是行:

return a + b / c * d;

对每个变量分别使用值 4、8、2 和 6 执行。

应用正常算术规则可以得出 28 的答案(先除法,然后乘法,最后加法)。

当您使用柯里化时,您正在编写一个接受一个参数的函数,这将 return 一个接受下一个参数的函数,直到提供所有参数。

在这种情况下,您需要调用 returned 函数 4 次,直到您到达最后一个函数并对所有参数求值。

这很好,因为您可以在代码执行期间的不同时间传入参数,并且可以使用已在最终函数的闭包中设置的参数创建新函数。例如

const fourPlusTwo = currying(4)(2)

现在您可以在代码中的任何地方使用新函数 fourPlusTwo,并且您将在其余两个函数的闭包中包含这些参数。

您拥有的代码是一个非标准示例,但如果您需要在整个应用程序中计算税费,您可以执行类似的操作。

const inclusiveTax = rate => amount => {
  return '$' + (amount * (rate / (100 + rate))).toFixed(2)
}

const norwayIncomeTax = inclusiveTax(60.2)
const strayaIncomeTax = inclusiveTax(32.5)
const muricaIncomeTax = inclusiveTax(31.5)

console.log(
  norwayIncomeTax(50000),
  strayaIncomeTax(50000),
  muricaIncomeTax(50000)
)

仅使用一个函数,您就可以为 3 个不同的国家/地区设置税率,并returned 等待金额的函数。

你应该知道函数对象和函数调用的区别。 like: var a = function(v){return v + 1;} a 是一个函数对象。然后 a(2) 调用函数 a.

尝试逐步理解该过程。

  1. currying 是一个函数,return 另一个函数。

  2. 所以currying(4)returns一个函数(a给定值4):

    function(b){
        return function(c){
            return function(d){
                return 4 + b /c * d;
                };
            };
        };
    };
    
  3. 那么currying(4)(8)也是'var a' return的另一个函数:

        function(c){
            return function(d){
                return 4 + 8 /c * d;
                };
            };
        };
    
  4. 正在调用 a(2) returns 函数对象:

            function(d){
                return 4 + 8 / 2 * d;
                };
            };
    
  5. 最后 a(2)(6) returns 4 + 8 / 2 * 6 即 28.