5

The value of 'a' seems to lose global scope when the constructor a is called.

var a = 6;

function b() {
    a = 10;

    function a() {}
    console.log(a); //10
}
b();
console.log(a); //6
user2430508
  • 1,011
  • 1
  • 7
  • 6

3 Answers3

6

The order is interpreted as shown below due to variable hoisting. Note that as @ShadowCreeper correctly points out, function a(){} is actually creating a local variable a inside of function b which is hoisted as shown below.

var a;
var b;

a = 6;
b = function() {
 var a;
 a = function(){};
 a = 10;
 console.log(a); //10
}
b();
console.log(a); //6
Travis J
  • 81,153
  • 41
  • 202
  • 273
  • Is defining `a` as a function inside `b` forcing `a` to be local to `b` , even without explicitly doing a `var a`. What is the magic behind the implicit local scope? – sabithpocker May 28 '13 at 23:58
  • 1
    @sabithpocker that's the default behavior of nested `function`'s, in that their local to the `function` their defined in ... https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope#Nested_functions_and_closures – Alex May 29 '13 at 00:01
  • Why does the hoisting behavior change when "function a() {}" is wrapped in parenthesis? http://jsfiddle.net/ZrgxX/ – user2430508 May 29 '13 at 00:31
  • @user2430508 - Because wrapping it in parenthesis makes it an expression and scopes the function definition to that expression. Consider this: http://jsfiddle.net/eVgw3/ , where you can clearly see that `a` is locally scoped to the expression. – Travis J May 29 '13 at 18:10
2

Because you are creating a local variable (the function a) then replacing that local variable's value (the function) with 10.

One way to avoid things like this is to precede all local variables and functions with "_" (underscore).

Shadow Man
  • 3,234
  • 1
  • 24
  • 35
  • 2
    If you put `var a = 10;` at the top of the `b` function, you will have a local variable that hides the global. I believe also that `function a ()` behaves the same as `var a = function ()` (creates a local variable named `a` that is a `function`). – Shadow Man May 28 '13 at 23:53
  • agreed, the implicit local declaration of the nested `function a` here is the kicker http://jsfiddle.net/AVcqr/ ... – Alex May 28 '13 at 23:56
  • Yes, @TravisJ explained it better though. I've never heard the term `hoisting`, that is new to me. :) – Shadow Man May 28 '13 at 23:58
2

This answer has a really nice explanation of what is going on here.

The summary is that Javascript is processed in two phases, compilation and then execution. The function definitions occur during the compilation step, so inside of b the compiler sees the definition function a() {} and the local variable a is created within the scope of b. Later on when the code is executed, the scope of b already contains the local variable a before any code is executed, so the line a = 10; is just giving the local variable a new value. The function definition was already processed during compilation so that will not happen during execution, so console.log(a) will output 10.

Community
  • 1
  • 1
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306