【问题标题】:Why do we have closures in JavaScript?为什么我们在 JavaScript 中有闭包?
【发布时间】:2010-07-20 10:08:00
【问题描述】:

我正忙于 JavaScript 闭包,并且正处于事情正在落实到位的地步; IE 闭包是函数的局部变量 - 在函数返回后保持活动状态,或者 闭包是一个堆栈帧,在函数返回时不会被释放。

我开始理解这个概念,但我理解的越多,我就越想知道为什么我们必须使用它们。

像这样的例子让我理解了这个概念,但让我问,有一种更简单的方法!

function sayHello(name) {
   var text = 'Hello ' + name;
   var sayAlert = function() { alert(text); }
   sayAlert();
}
sayHello('Gath');

我只是想知道为什么我必须保持局部变量活着?函数退出后?

我在哪里可以获得显示由闭包实现的解决方案的示例,并且除了闭包之外没有其他方法可以工作?

【问题讨论】:

标签: javascript closures


【解决方案1】:

闭包增加了语言的表达能力。由于闭包,有些模式可以很容易地实现。想到的几个例子包括:

【讨论】:

    【解决方案2】:

    “闭包是穷人的对象。对象是穷人的闭包。” (抱歉,我忘记出处了)。

    有时我们需要只有一个代码块才需要的变量。我们将该代码块放在一个函数中,并将这些变量作为该函数的局部变量。

    有时我们需要所有程序中的函数/代码块所需的变量。我们可以将这些变量作为全局变量。

    有时我们需要一些函数/代码块所需的变量。例如,我们有一个名为 Sales 的实体,我们希望将所有与销售相关的代码放在一起。所以我们有一组函数和一组处理销售的变量。我们可以将这些函数和变量放在一个对象中,以便将它们(函数和变量)与代码的其他部分隔离。

    在不直接支持对象的语言中,我们可以有嵌套函数。外部函数的作用类似于类,内部函数的作用类似于方法。外部函数的局部变量就像字段一样,它们只能被内部函数访问。在随后对内部函数的调用中,我们希望维护局部到外部函数变量的状态,这就是需要闭包的地方。我们所要做的就是通过外部函数的输出传递对任何内部函数的引用,到外部函数之外的代码,这样内部函数访问的外部函数的变量即使在外部函数退出后也被保留。

    【讨论】:

    • 我想我喜欢这个,但最后一段让我头晕目眩……你能添加一些代码来解释这些类比吗?
    【解决方案3】:

    闭包是一个具有执行它所需的所有环境的函数。 在 javascript 中,它是在创建匿名函数 (= lambda) 时,使用来自外部范围的变量。

    您可以通过这样的代码更好地理解原因:

    function foo()
    {
      var text = computeFromOutside();
      // ... other lines of code
      return function(otherText) { return text + otherText; }
    }
    
    bar = foo();
    
    function baz(fun)
    {
      return fun("some text");
    }
    

    在这里,您将返回一个使用局部变量“text”的函数。 因此,您将离开 foo 函数范围,破坏其变量。 然而,由于我们有一个使用文本的匿名函数,我们必须跟踪这个变量。 这可以通过值或引用来实现,具体取决于语言(使变量保持活动状态(之后可以修改它,或者在创建函数时复制它的值)。

    我希望这会有所帮助!

    【讨论】:

      【解决方案4】:

      你选择的例子出现在this page,所以我假设你是从那里拿的。你看过它提供的所有其他例子吗?他们比我可能更好地解释了关闭的动机。

      【讨论】:

      • 是的,我做到了,但他们仍然没有展示其他一切都失败并且关闭是唯一可以解决问题的场景
      • @gath - 是的。其中许多示例是具有其他函数作为其返回值的函数。如果您调用外部函数,保存对返回函数的引用,然后在稍后调用返回函数,这些示例不可能在没有闭包的情况下工作。
      • @gath:一切都可以用汇编程序编写。闭包不是为了解决以前无法解决的问题而发明的,所以你不会发现任何只能用闭包解决的问题。它们使某些问题更容易解决,如果您带着这一点重新审视这些示例,它们可能会开始对您更有意义。
      【解决方案5】:

      一个普通的函数做它的事情,计算一个结果并返回它。通过返回一个闭包,您可以将您的工作打包到一半,并让调用者在准备好时获得更多。自从我在大学尝试Scheme 以来,我一直渴望在我使用过的每一种语言中都使用闭包……它们正在形成危险的习惯!

      它们也可以说是未来的重要组成部分:与其他似乎非常适合多核系统并行编程的函数式编程机制一起使用。

      【讨论】:

        猜你喜欢
        • 2012-08-31
        • 2022-01-18
        • 2010-11-21
        • 2012-04-28
        • 1970-01-01
        • 1970-01-01
        • 2018-12-04
        • 1970-01-01
        相关资源
        最近更新 更多