Reputation: 21
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/
Upvotes: 2
Views: 58
Reputation: 1550
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();
}());
Upvotes: 0
Reputation: 13853
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);
}
Upvotes: 1
Reputation: 3045
The line starting with (function() {
creates a scope/closure that encloses bar, foo vars whose values are not valid outside scope/closure
Upvotes: 0