James Allardice
James Allardice

Reputation: 165971

Why do variables of inner functions not leak to the outer scope?

Consider the following snippet of JavaScript:

function outer() {
    var x = 10;
    function inner() {
        var y = 20;
    }
}

Obviously, the variable y is not available in the context of outer. Following through the process in the ES5 spec tells us that this is what happens when we enter the outer execution context:

The [[Code]] internal property of a function is described in Creating Function Objects (13.2). It refers to the FunctionBody as specified by the grammar (the entire contents of the function):

function Identifier ( FormalParameterListopt ) { FunctionBody }

At this point we enter the Declaration Binding Instantiation (10.5) section and do the following:

My question is why, at this point, are bindings not created for variable declarations from inner functions? It seems like code should still contain the entire source text of the outer function (which would include the source text of the inner function). I'm looking for something in the spec which explains the behaviour.


Updated, to be a bit clearer: I am asking about what happens when we enter the context of the outer function. The inner function is never called, and I don't care about what happens when we return from the outer function. I am purely interested in the process, as defined by the spec, of creating bindings for variable declarations when entering a new execution context.

Upvotes: 4

Views: 252

Answers (2)

Bergi
Bergi

Reputation: 664599

It's right there in the definition of the term code (§10.1):

Function code is source text that is parsed as part of a FunctionBody. The function code of a particular FunctionBody does not include any source text that is parsed as part of a nested FunctionBody.

Upvotes: 0

Christoph
Christoph

Reputation: 51201

You have a error in your thinking.

Javascript has function-scope. Thus you have a new execution context for each function, thats true. However, after you return from a function this function context expires. That is the reason why you can't access the variables from the inner function after it has returned. You still are in the execution-context of the outer-function but you can't access the execution-context of the inner function anymore.

Citing the spec:

Every return exits an execution context. A thrown exception may also exit one or more execution contexts.

EDIT: To clarify this further: The body of a function declaration is NOT being processed (see 10.5.5.d), only the function identifier and the arguments are passed to the variable environment.

Upvotes: 1

Related Questions