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

// This celebrity is Michael Jackson


halfer
  • 19,824
  • 17
  • 99
  • 186
  • That's just the *magic* of closures :-) The variables that are still referenced are not garbage-collected even when the outer function returns. – Bergi Sep 03 '14 at 18:43

3 Answers3

1

Variable nameIntro is a non-local variable for the lastName-function. The variable nameIntro is stored in the heap instead of stack (in contrast to local variables, which are stored in the stack).

A quote from the Wikipedia article:

If the nested function is passed as an argument to a higher-order function a closure needs to be built in order to locate the non-local variables. If the nested function is returned as a result from its outer function (or stored in a variable) the non-local variables will no longer be available on the stack. They need to be heap allocated instead, and their lifetime extend beyond the lifetime of the outer function that declared and allocated them. This generally requires garbage-collection.

heikkim
  • 2,955
  • 2
  • 24
  • 34
1

Well, that's the magic of closures. Different languages implement it differently. In JavaScript, you can imagine that a function object consists not only of code, but also a reference to an "environment" where it can look up non-local variables ("free variables"). When a function is created, this environment is set to the scope in which it was created. In the case of lastName, the scope in which it was created is the body of the celebrityName function.

Then, later when the lastName function executes and it needs to lookup nameIntro which is not a local variable, it looks in this environment that it kept. Note that this means even though the celebrityName function has returned, its scope (including the nameIntro variable) still exists and is accessible by the lastName function which has a reference to it.

halfer
  • 19,824
  • 17
  • 99
  • 186
newacct
  • 119,665
  • 29
  • 163
  • 224
1

The function that you have written can also be written as:

//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"); 

If you do not apply a closure then the scope of the outer variables will get lost when the garbage collector runs. Hence you would not be able to access it later.

However when a closure is applied and the outer variable is accessed by a "returning" function then a binding is maintained between them which does not allow the garbage collector to delete that. Hence you get the values

Working Fiddle to demonstrate Closure

V31
  • 7,626
  • 3
  • 26
  • 44