即使在外部函数返回后,闭包如何访问外部函数的变量?

时间:2014-09-03 10:45:41

标签: javascript function closures

function celebrityName (firstName) {
     var nameIntro = "This celebrity is ";
     function lastName (theLastName) {
        return nameIntro + firstName + " " + theLastName;
    }
    return lastName;
}
var mjName = celebrityName ("Michael");
mjName ("Jackson"); 

//这个名人是Michael Jackson

3 个答案:

答案 0 :(得分:1)

变量nameIntronon-local variable - 函数的lastName。变量nameIntro存储在heap而不是stack中(与存储在堆栈中的局部变量形成对比)。

来自维基百科文章的引用:

  

如果嵌套函数作为参数传递给更高阶   函数需要构建一个闭包来定位非本地的   变量。如果嵌套函数作为其结果返回   外部函数(或存储在变量中)的非局部变量将   不再可用于堆栈。他们需要堆分配   相反,它们的寿命超出了外部的寿命   声明和分配它们的函数。这通常需要   垃圾收集。

答案 1 :(得分:1)

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

然后,稍后当lastName函数执行并且需要查找不是局部变量的nameIntro时,它会在此环境中查找它保留的内容。请注意,这意味着即使celebrityName函数已返回,其范围(包括nameIntro变量)仍然存在,并且可由lastName函数访问,该函数具有对它的引用。

答案 2 :(得分: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