2015-11-03 69 views
1

我想深入了解关闭java脚本的概念。Javascript关闭和堆栈展开

function foo(){ 
    let temp = 5; 
    let bar = function _bar(){ 
      console.log('temp:=', temp); 
    } 
    return bar; 
} 

let ref2Bar = foo(); 
ref2Bar(); 

o/p: 
temp:=5 

从上面的示例代码片段中,bar()与foo()更接近。 ref2Bar得到bar()的引用并从全局范围执行它可以访问foo()的词法范围。

现在我来自堆栈缠绕& un-winding东西。当foo()完成时,应该弹出堆栈,但由于bar()的引用在该文件的生命周期中处于活动状态,所以它听起来像foo范围仍然可以访问。我很想知道这是如何处理的。另外,如果有更多的关闭,会有一个公平的机会跑出内存?

+0

您需要多少封闭内存才能用完?我假设有十几二十个。你打算创建多少个?当所有对引用的引用超出范围时,封闭本身也会被销毁,所以由您决定不保留不需要的引用。 – tadman

+0

你有这个措词后退 - 'foo'是'bar'上的闭包,因为'foo'环绕它来创建外部范围。但你似乎正在考虑正确的范围。 –

+1

@DanLowe:没有,正确的术语确实是'_bar'关闭了'foo'的词法范围(包含'temp'和'bar'),因此是闭包。 – Bergi

回答

3

foo()完成后,它应该被弹出堆栈

是,它不再是活跃的。

但作为bar引用是在这个文件的寿命活跃,这听起来像foo范围仍然可以访问。

事实确实如此。

我很好奇,想知道这是怎么处理

变量环境(“范围”),其中包含已关闭了需要在堆上要分配的变量,而不是在叠加。从调用栈中弹出的执行上下文(“栈帧”)仅包含一个指向它的指针。
因此,可变环境不会被垃圾收集,直到_bar/ref2bar的引用被破坏。

此外,如果有更多的关闭,是否会有一个公平的机会运行内存不足?

是的,每个闭包都是一个对象并占用内存空间。如果您创建了多个关闭具有较大值的变量的闭包,则确实会导致内存泄漏。我不会称之为“公平的机会”,但你需要非常多的或非常大的。