【问题标题】:Javascript Closure called automatically vs manuallyJavascript Closure 自动调用 vs 手动调用
【发布时间】:2018-04-22 03:40:00
【问题描述】:

我对这两个闭包函数感到困惑。

当我将 doSomeMath 分配给变量 test 时,doSomeMath 返回函数而不执行它。它只会在我执行 test(); 时运行闭包函数; 但是,showName 函数并非如此。只要我传入值,它就会立即调用闭包函数而不是返回它。

谁能给我解释一下?谢谢。

function showName (firstName, lastName) {
    var nameIntro = "Your name is ";
    // this inner function has access to the outer function's variables, including the parameter
    function makeFullName () {     
        var full = nameIntro + firstName + " " + lastName; 
        return full;   
    }

    return makeFullName ();
}

showName ("Michael", "Jackson"); // Your name is Michael Jackson


function doSomeMath(a, b) {
    var a = a;
    var b = b;

    function multiply() {
        var result = a * b;
        return result;
    }

    return multiply;
}

var test = doSomeMath(5,10);
test();

【问题讨论】:

  • 我不明白这个问题 - 就像你说的那样。其中一个返回一个函数,另一个返回一个值(立即调用函数的结果)。
  • @CertainPerformance 是的。为什么呢?第一个立即返回值,而第二个返回一个函数
  • return makeFullName ();return multiply;。您可以看到第一个被调用,而第二个没有。 (但你应该更好地格式化 - 函数名应该紧挨着它们的括号)
  • @CertainPerformance 天哪!我一遍又一遍地查看代码并没有注意到这一点。谢谢!!
  • 您可能想阅读 MDN 上的 Closures

标签: javascript closures


【解决方案1】:

这两个函数是演示闭包如何工作的两种不同方式。

你可以很容易地做相反的事情来达到同样的效果。

function doSomeMath(a, b) {
    var a = a;
    var b = b;

    function multiply() {
        var result = a * b;
        return result;
    }

    return multiply();
}

doSomeMath(5,10) //50

在上面的代码中,您返回的是内部函数的调用结果,而不是函数本身。在这里,如您所见,multiply 有超过 5 和 10 的闭包,因此您得到的结果为 50。

同样,尝试:

function showName (firstName, lastName) {
    var nameIntro = "Your name is ";
    // this inner function has access to the outer function's variables, including the parameter
    function makeFullName () {     
        var full = nameIntro + firstName + " " + lastName; 
        return full;   
    }

    return makeFullName;
}

var show = showName ("Michael", "Jackson");
show() //"Your name is Michael Jackson"

上面的代码返回内部函数而不是它的调用,并反过来演示了内部函数makeFullName如何对外部函数的nameIntro变量进行闭包。

另一个答案提供了对闭包的简明理解。要了解更多信息,请阅读 closures 以更好地理解上述示例。

【讨论】:

    【解决方案2】:

    我认为您混淆了闭包和高阶函数。

    没有手动调用函数这样的概念。必须始终调用函数。如果函数是闭包,这不会改变。

    事实上,有人可能会说这是闭包作为一种抽象机制的本质力量。

    闭包是一个引用其封闭范围内元素的函数。

    这通常被称为词法作用域。

    闭包引用的封闭范围的元素集合称为其环境。

    一个不引用其封闭范围内元素的函数可以被认为是一个退化的闭包 - 一个具有空环境的闭包。

    一个函数返回的值可能是另一个函数,但这与闭包的概念完全正交。

    在 JavaScript 中,就像在许多语言中一样,函数是一等值。这意味着它们可以存储在变量中、作为参数传递并作为结果返回。

    考虑

    var createIncrement = function (incrementBy) {
      return function (value) {
        return value + incrementBy;
      };
    };
    

    上面的函数是高阶函数,因为它返回一个函数。 顺便说一句,它也是一个闭包,因为它引用了incrementBy,它在封闭范围内声明。

    在您的问题框架中表达的混淆可能源于这样一个事实,即在实践中,即使是最简单的 JavaScript 程序也会同时使用这两个功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-17
      • 2015-11-20
      • 2015-08-04
      • 2016-08-08
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多