2

Whats happening to bar on the second console.log? Shouldn't it be "Andy" or throw a Reference Error? Also, why is foo not undefined?

Using Chrome.

// lexical scope example
var bar = "Andy";
try {
    console.log(bar); // Andy
    (function() {
        console.log(bar); // undefined!
        var bar = "B",
            foo = "Last Name";
        console.log(bar); // B
        console.log(foo); // Last Name
    })();
    console.log(bar); // B
    console.log(foo); // Reference Error
} catch (e) {
    console.log(e);
}​

JSFiddle of the above: http://jsfiddle.net/2D9fj/3/

hellslam
  • 1,550
  • 11
  • 17
matt long
  • 21
  • 1
  • Related to http://stackoverflow.com/questions/1552941/variables-in-anonymous-functions-can-someone-explain-the-following? – j08691 May 17 '12 at 15:43

3 Answers3

1

The var declarations are hoisted, after being parsed your code looks like, (this is why a lot of developers define their vars all at the top)

// lexical scope example
var bar = "Andy";
try {
    console.log(bar); // Andy
    (function() {
         var bar, foo;
        console.log(bar); // undefined!
        bar = "B";
        foo = "Last Name";
        console.log(bar); // B
        console.log(foo); // Last Name
    })();
    console.log(bar); // B
    console.log(foo); // Reference Error
} catch (e) {
    console.log(e);
}​
Andrew
  • 13,757
  • 13
  • 66
  • 84
0

The line starting with (function() { creates a scope/closure that encloses bar, foo vars whose values are not valid outside scope/closure

rt2800
  • 3,045
  • 2
  • 19
  • 26
0

Andrew's answer is correct, but I think it would be useful to provide an example that just illustrates the hoisting concept, without the additional code.

// this: 
function foo() {
    console.log(x);
    var x = 1;
}

//is actually interpreted like this:
function foo() {
    var x;
    console.log(x);// undefined
    x = 1;
}

Also, closure is related to this issue, but only so much as it makes it harder to identify hoisting errors.

(function parent() {
  // x declared and assigned in parent scope
  var x = 2;

  function foo() {
      console.log(x); // 2 (closed around parent scope)
  }

  function bar() {
      console.log(x); // undefined (bar scope, x declaration is hoisted, but not defined yet)
      var x = 1;
  }
  function baz() {
      var x = 3;
      console.log(x); // 3 (baz scope, defined)
  }
  //run 
  foo();
  bar();
  baz();
}());
hellslam
  • 1,550
  • 11
  • 17