Search code examples
javascriptfunctionlexical-scope

JS - Declare nested function outside the outer function


case 1: I understand why it works in this case:

function foo(arg) {
  var outer = " this is the outer variable";
  function bar() {
    console.log("arg: " + arg);
    console.log("outer variable: ", outer);
  }
  bar();
}

console.log(foo("hello"));

case 2: But I don't understand why the following doesn't work if declare the bar function outside, separately:

function foo(arg) {
  var outer = " this is the outer variable";

  bar();
}

function bar() {
  console.log("arg: " + arg);
  console.log("outer variable: ", outer);
}

console.log(foo("hello"));

case 3: If I add arguments to bar function:

function foo(arg) {
  var outer = " this is the outer variable";

  bar();
}

function bar(arg, outer) {
  console.log("arg: " + arg);
  console.log("outer variable: ", outer);
}

console.log(foo("hello"));

The output:

"arg: undefined"
"outer variable: " undefined

My question is regarding the case 2: why bar() doesn't reach the variables defined inside the foo()?

Edit case 2:

Have learnt from all feedbacks, I have added arguments to bar(arg, outer), and it works. Thanks a lot.

function foo(arg) {
    var outer = " this is the outer variable";

    bar(arg, outer);
}

function bar(arg, outer) {
    console.log("arg: " + arg);
    console.log("outer variable: ", outer);
}

console.log(foo("hello"));

It works.


Solution

  • When bar is defined, its scope chain is created, preloaded with the global variable object, and saved to the internal [[Scope]] property. When bar is called, an execution context is created and its scope chain is built up by copying the objects in the function’s [[Scope]] property

    so,if you give bar two arguments arg,outer,that is gonna work:

    function foo(arg) {
      var outer = " this is the outer variable";
    
      bar();
    }
    
    function bar(arg,outer) {
      console.log("arg: " + arg);
      console.log("outer variable: ", outer);
    }
    
    console.log(foo("hello"));
    

    Professional JavaScript for Web Developers.3rd.Edition.Jan.2012

    p222