Lexical Scoping and Nested Functions

Functions in JavaScript are lexically rather than dynamically scoped. This means that they run in the scope in which they are defined, not the scope from which they are executed. Prior to JavaScript 1.2, functions could be defined only in the global scope, and lexical scoping was not much of an issue: all functions were executed in the same global scope (with the call object of the function chained to that global scope).

In JavaScript 1.2 and later, however, functions can be defined anywhere, and tricky issues of scope arise. For example, consider a function g defined within a function f. g is always executed in the scope of f. Its scope chain includes three objects: its own call object, the call object of f( ), and the global object. Nested functions are perfectly understandable when they are invoked in the same lexical scope in which they are defined. For example, the following code does not do anything particularly surprising:

var x = "global";
function f(  ) {
    var x = "local";
    function g(  ) { alert(x); }
    g(  );
}
f(  );  // Calling this function displays "local"

In JavaScript, however, functions are data just like any other value, so they can be returned from functions, assigned to object properties, stored in arrays, and so on. This does not cause anything particularly surprising either, except when nested functions are involved. Consider the following code, which includes a function that returns a nested function. Each time it is called, ...

Get JavaScript: The Definitive Guide, Fourth Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.