Nested Scope

We said that Scope is a set of rules for looking up variables by their identifier name. There’s usually more than one Scope to consider, however.

Just as a block or function is nested inside another block or function, scopes are nested inside other scopes. So, if a variable cannot be found in the immediate scope, Engine consults the next outer containing scope, continuing until found or until the outermost (aka, global) scope has been reached.

Consider:

  1. function foo(a) {
  2. console.log( a + b );
  3. }
  4. var b = 2;
  5. foo( 2 ); // 4

The RHS reference for b cannot be resolved inside the function foo, but it can be resolved in the Scope surrounding it (in this case, the global).

So, revisiting the conversations between Engine and Scope, we’d overhear:

Engine: “Hey, Scope of foo, ever heard of b? Got an RHS reference for it.”

Scope: “Nope, never heard of it. Go fish.”

Engine: “Hey, Scope outside of foo, oh you’re the global Scope, ok cool. Ever heard of b? Got an RHS reference for it.”

Scope: “Yep, sure have. Here ya go.”

The simple rules for traversing nested Scope: Engine starts at the currently executing Scope, looks for the variable there, then if not found, keeps going up one level, and so on. If the outermost global scope is reached, the search stops, whether it finds the variable or not.

Building on Metaphors

To visualize the process of nested Scope resolution, I want you to think of this tall building.

Nested Scope - 图1

The building represents our program’s nested Scope rule set. The first floor of the building represents your currently executing Scope, wherever you are. The top level of the building is the global Scope.

You resolve LHS and RHS references by looking on your current floor, and if you don’t find it, taking the elevator to the next floor, looking there, then the next, and so on. Once you get to the top floor (the global Scope), you either find what you’re looking for, or you don’t. But you have to stop regardless.