The Great Escape
The plot thickens when function references come into play. Some languages, such as Pascal, do allow the use of inner functions for the purpose of code hiding, and those functions are forever entombed within their parent functions. JavaScript, on the other hand, allows us to pass functions around just as if they were any other kind of data. This means inner functions can escape their captors.
The escape route can wind in many different directions. For example, suppose the function is assigned to a global variable:
var globVar; function outerFun() { function innerFun() { alert('hello'); } globVar = innerFun; } outerFun(); globVar();
The call to outerFun()
after the function definition modifies the global variable globVar
. It is now a reference to innerFun()
. This means that the later call to globVar()
operates just as an inner call to innerFun()
would, and the alert is displayed. Note that a call to innerFun()
from outside of outerFun()
still results in an error! Though the function has escaped by way of the reference stored in the global variable, the function name is still trapped inside the scope of outerFun()
.
A function reference can also find its way out of a parent function through a return value:
function outerFun() { function innerFun() { alert('hello'); } return innerFun ; } var globVar = outerFun(); globVar();
Here, there is no global variable modified inside outerFun()
. Instead, outerFun()
returns a reference to innerFun()
. The call to outerFun()
results in this reference, which can be stored and called itself in turn, triggering the alert again.
The fact that inner functions can be invoked through a reference even after the function has gone out of scope means that JavaScript needs to keep referenced functions available as long as they could possibly be called. Each variable that refers to the function is tracked by the JavaScript runtime, and once the last has gone away the JavaScript garbage collector comes along and frees up that bit of memory.