闭包:在函数返回后,如何使局部变量保持活动状态

Closures: How is it possible for a local variable to be kept alive after the function has returned?

本文关键字:局部变量 何使 活动状态 函数 返回 闭包      更新时间:2023-09-26

我刚刚读到局部变量只存在到声明它的函数结束。

谢谢大家的回答。我的主要问题是这两种说法相互矛盾。那么哪一个是真的呢?我想矛盾只是表面的。

我猜垃圾收集器会擦除"关闭"变量......

好吧,现在,很抱歉太啰嗦了,我想我需要更多地练习橡皮鸭技术。

我刚刚意识到我们在闭包中声明了一个局部变量,然后垃圾收集器不会擦除该变量,因为我们持有返回对象的引用,对吧?

所以?内存泄漏?有什么选项可以检查此类变量的列表并清理它们吗?

您想知道该功能是如何在内部实现的吗?不同的js引擎可以在那里使用不同的策略。重要的是语言的行为是什么样的。

JavaScript 的创建者 Brendan Eich 是 Scheme 的忠实粉丝,因此在 JS 中添加了行为与 Scheme 闭包完全相同的闭包。Scheme的一位创建者在1986年的一系列讲座中给出了闭包如何工作的最佳解释之一,称为"计算机程序的结构和解释",特别是讲座7A和7B,他谈到了编写解释器并解释了参数和局部变量如何存储在闭包关闭的"环境"中。顺便说一句。术语"环境"现在的使用方式不同,至少在 JavaScript 世界中是这样,但闭包的工作方式仍然与当时相同。

打开它的范围。

样本 1

function() {
   var localVarThatWouldGo = "hi";
   // set to window scope
   window.myVar = localVarThatWouldGo;
}

但是设置全局范围的变量不是好的做法。相反,请将其设置为所需的范围。例如,如果您的应用程序位于如下所示的视图模型中:

样本 2

function runApp() {
    // point to this object
    var self = this;
    this.myFunction = function() {
          self.scopedVariable = "hi"; // this won't go for the life time of the app variable below
    }
}
var app = new runApp()

闭包实际上只是一个巧妙的编译器技巧。当编译器检测到变量"闭合"的情况(变量在嵌套作用域中以词法方式使用)时,它会在后台为您生成一个新对象,并将局部变量分配给生成对象上的字段。作为开发人员,您永远不必担心generatedObject.yourVariable访问该变量,编译器基本上为您别名。

var getTimeSinceStartUp = (function() {
   var time = new Date();    //time is 'closed over', it 'leaks' into the sub scope
   return function() {
    return new Date() - time; //time is available here because of the hidden type the compiler made for you.
  });
})();
var ms = getTimeSinceStartup();