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.