Question

I'm trying to figure out how closures are implemented in JS (in theory), and there's one thing that confuses me and I couldn't find an answer to.

Closures in JS use a chain of Activation Objects. Each function invocation has one, and it points to its parent's Activation Object, which points to its parent's Activation Object and so on.

If I understand correctly, the "parent" in this case is the function call in which the child function was defined in.

But how does the child know its parent's Activation Object? The child function could have been called anywhere in the program, even outside of the function call that defined it. Is the Activation Object of the parent somehow stored in the function object itself when the function is defined? Does every function invocation somehow get its parent's Activation Object from its own function object? That's the only explanation I could think of, but I couldn't verify it.

Also, is there a way to inspect an Activation Object (much like how __proto__ can be inspected)?

Was it helpful?

Solution

At least by ECMA's terms, what you're describing is defined as a Lexical Environment.

A Lexical Environment consists of an Environment Record and a possibly null reference to an outer Lexical Environment.

And each function is defined as having an internal [[Scope]] property (ref: Table 9), which references one such environment.

Function.[[Scope]] ->
  LexicalEnvironment.Outer ->
    LexicalEnvironment
    # etc.

The .Outer property in this is just a guess, but however the engine refers to the outer environment, its value is that of the current context's environment -- the [[Scope]] of the surrounding function or of the program itself.

When a function is called and references a variable, the engine can walk through the "scope chain" of environments and their records until it either finds the name being referenced or runs out of environments and throws a ReferenceError.


Also, is there a way to inspect an Activation Object (much like how __proto__ can be inspected)?

It's not currently possible within the language itself. Internal properties can't be accessed directly within JavaScript and the [[Scope]] property doesn't have anything to expose it like the [[Prototype]] property has Object.getPrototypeOf() or __proto__.

But, as Bergi mentioned, JavaScript debuggers may allow you to inspect the scope chain. For example, under "Scope Variables" in Chrome's Web Tools:


(source: google.com)

While a script is paused, you can see the current call stack and in-scope variables in the right-hand side bar.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top