0

I'm playing with closure and have no problem understanding how inner functions have access to outer lexical environments:

function outer() {
  var bar = 0;
  function inner() {
    console.log(bar);
  }
  inner();
}
outer();    // prints '0'

But what gets me is this:

function foo() {
  return function inner() {
    console.log(bar);
  }
}
function outer() {
  var bar = 0;
  var fakeInner= foo();    // not the same as "var fakeInner= function () { console.log(bar); }"
  fakeInner();
}
outer();    // ReferenceError: bar is not defined

Here I try to "define" an "inner function" fakeInner by assigning it to a function expression returned from an outside function.

I used to think that JavaScript creates the fakeInner inside with a "copy" of its code, something like: var fakeInner= function () { console.log(bar); }, which would then have access to bar, but this is not the case -- it appears when fakeInner is invoked, JavaScript traces back to its definition. Am I understanding this correctly? That is, function objects (either declarations or expressions) are mere references to their definition spots, and passing them do not change their lexical environments (hence inner functions have to be defined inside with explicit syntax)?

Yibo Yang
  • 2,353
  • 4
  • 27
  • 40

3 Answers3

1

Yes, functions do only have access to their own lexical environment - from where they were defined. JavaScript does not have dynamic scope where a function has any kind of access to the scope where it is called.

This happens by attaching the scope to the function object, it is a part of the closure.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

In this example,

function outer() {
  var bar = 0;

  function inner() {
    console.log(bar);
  }
  inner();
}
outer();

scope of bar is outer function and will be available for all function defined in it.

function foo() {
  return function inner() {
    console.log(bar);
  }
}

function outer() {
  var bar = 0;
  var fakeInner = foo(); // not the same as "var fakeInner= function () { console.log(bar); }"
  fakeInner();
}
outer();

In this example, again bar is accessible inside outer but foo is outside it. Hence reference error is thrown.

Also refer What is the scope of variables in JavaScript? for more information.

Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79
0

The scope of inner functions is its own outer function. Not the function it is being called from.

poushy
  • 1,114
  • 11
  • 17