2014-09-03 194 views
0
function celebrityName (firstName) { 
    var nameIntro = "This celebrity is "; 
    function lastName (theLastName) { 
     return nameIntro + firstName + " " + theLastName; 
    } 
    return lastName; 
} 
var mjName = celebrityName ("Michael"); 
mjName ("Jackson"); 

//这是名人迈克尔·杰克逊即使外函数返回,闭包如何访问外函数的变量?

+0

这只是关闭:-)仍在引用的变量*魔法*没有垃圾收集,即使外部函数返回。 – Bergi 2014-09-03 18:43:56

回答

1

可变nameIntro对于lastName -function一个non-local variable。变量nameIntro存储在heap而不是stack中(与存储在堆栈中的局部变量相反)。

从维基百科的文章引述:

如果嵌套函数作为参数传递给高阶 功能的关闭需要建立的顺序传递找到非本地 变量。如果由于其外部函数(或存储在变量中)而导致嵌套函数返回,则非本地变量 将不再可用于堆栈。它们需要被分配为 的堆,并且它们的寿命延长超过声明和分配它们的外部功能 的寿命。这通常需要 垃圾收集。

1

那么,这是关闭的魔力。不同的语言以不同的方式执在JavaScript中,您可以想象一个函数对象不仅包含代码,还包含对可以查找非本地变量(“自由变量”)的“环境”的引用。当一个函数被创建时,这个环境被设置为它创建的范围。在lastName的情况下,它的创建范围是celebrityName函数的主体。

然后,在稍后当lastName函数执行并且需要查找nameIntro这不是本地变量时,它会在它保留的环境中查找。请注意,这意味着即使celebrityName函数已返回,它的作用域(包括nameIntro变量)仍然存在,并可由提及它的lastName函数访问。

1

,你写的函数也可以写为:

//Your Function 
function celebrityName (firstName) { 
    //Outer Variable 
    var nameIntro = "This celebrity is "; 
    //returned Function 
    return function(theLastName) { 
     //returned value of the function that is returned 
     return nameIntro +firstName + " " + theLastName; 
    } 
} 

//the returned function is mapped to mjName 
var mjName = celebrityName ("Michael"); 
//Output of the returned function 
mjName ("Jackson"); 

如果不应用一个闭合那么垃圾回收器运行时的外部变量的作用域会迷路。因此,您以后将无法访问它。

但是,当应用闭包并通过“返回”函数访问外部变量时,则会在它们之间保留一个不允许垃圾收集器删除它的绑定。因此,你得到的值

Working Fiddle to demonstrate Closure