3

I was reading this article and I have some questions please:

considering this code :

1:   var a = 1;
2:   function b () {
3:       a = 10;
4:       return;
5:       function a() {}
6:   }
7:   b();
8:   alert(a);

this will alert 1. ( my question is why ? )

the article states its related to Name resolution.

Name resolutions (according to the article ) is being determined by this order:

1. Internal mechanisms of language: for example, in all scopes are available “this” and “arguments”.
2. Formal parameters: the functions can be named as the formal parameters, which scope is limited to the function body.
3. Function declarations: declared in the form of function foo() {}.
4. Variable declarations: for example, var foo;.

line #3 suppose to change the value of the global a. but the function a(){...} have a priorty over the inside a declaration ( If i understood correctly) and thats why is alerts 1

p.s. if i remove line #5 , it will alert 10.

In general, if a name is already defined, it will never be redefined by another entity with the same name. That is the function declaration has a priority over the declarations of the variable with the same name. But this does not mean that the value of a variable assignment does not replace the function, just its definition will be ignored.

I dont understand that part :

But this does not mean that the value of a variable assignment does not replace the function

so 2 questions please :

  • Did I understand correctly the reason for alerting 1

  • What does the above line means ? (the misunderstood part)

thanks.

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • i know this isn't an answer, but couldn't we just give functions and variables proper names and not worry about what happens under ficticious circumstances? – jbabey Sep 05 '12 at 17:52
  • @jbabey some people like to go deeper into things to see how they works in different scenarios. this is one of them. the name is not importand here . its just an example. – Royi Namir Sep 05 '12 at 17:53
  • 1
    My apologies, Royi, for posting the same article. Thank you for graciously bringing that to my attention. – steve-er-rino Sep 05 '12 at 18:01

3 Answers3

7

Did I understand correctly the reason for alerting 1

Yes

"But this does not mean that the value of a variable assignment does not replace the function"
What does the above line means ? (the misunderstood part)

It just means that although a function with name a is already defined, a = 10 is still going to be executed, i.e. after that line a does not refer to a function anymore but to 10.

I assume they wanted to relax the previous statement a bit and avoid that people incorrectly think that because the function declaration is executed first, the assignment would not take place anymore.


Function and variable declarations are hoisted to the top of the scope. So the code is equivalent to:

1:   var a = 1;
2:   function b () {
3:       function a() {}
4:       a = 10;
5:       return;
6:   }
7:   b();
8:   alert(a);

function a() {...} creates a symbol (variable) a in the local scope and its value is the very same function. The next line, a = 10;, then assigns a new value to that symbol, namely a number.

var a = 1;
function b () {
     function a() {} // creates a new local symbol `a`, shadowing the outer `a`
     // until here, `a` refers to the function created 
     // created by the above declaration
     a = 10; // now a new value is assigned to the local symbol/variable `a`
     // from here on, `a` is `10`, not a function
     return;
}
b();
alert(a);
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
3
var a = 1;
function b () {
    var a = 10;
}
b();
alert(a);

does the above example make sense to you? Yes? Good, then you understand the difference between local and global scope...

var a = 1;
function b () {
    a = 10;
    var a;
}
b();
alert(a);

Does this example make sense to you? Yes? Then you understand that it does not matter where a variable is declared in a function, it will always be declared when first entering the function.

var a = 1;
function b () {
    a = 10;
    var a = function() { };
}
b();
alert(a);

Now, does this example make sense? Yes? Then you understand dynamic typing. A variable can be assigned a function as a value and then can be overwritten with a integer such as 10.

var a = 1;
function b () {
    a = 10;
    return;
    function a() { }
}
b();
alert(a);

Now your example should make sense because we are just changing the way we declare a, but its the same thing.

hackattack
  • 1,087
  • 6
  • 9
  • 1
    "A variable can be assigned a function as a value and then can be overwritten with a integer" - true, but not the case here. The function assignment is never executed because it follows a `return` statement. It is only the `var a;` that gets hoisted. – pimvdb Sep 05 '12 at 18:10
  • @pimvdb function declarations are hoisted along with their body - it does not get split out into seperate declaration/assignment statements. – jbabey Sep 05 '12 at 18:11
  • I thought you were referring to `var a = function() { };` with that sentence. Note the difference with a function declaration. – pimvdb Sep 05 '12 at 18:12
  • @pimvdb is correct, my bad. The variable a gets defined, assigned the value 10 and then overwritten with the function value. I wanted to get the point across that that it doesn't matter what a is associated with at first site because it can be overwritten with any value. I guess my example here was not the best, good catch. – hackattack Sep 05 '12 at 18:15
  • @jbabey I dont understand. The function has a priority over the `var a` , so if it has a priority why does `var a` still executed ? – Royi Namir Sep 05 '12 at 18:16
2

From my understanding of hoisting, both variable declarations and function declarations are hoisted. Therefor, here's what's happening:

var a; // a is declared (hoisted)
function b () { // function declaration (hoisted)
    function a () {} // function declaration (hoisted)
    a = 10; // an assignment to the local a that was hoisted, not the outer a
    return;
}
a = 1; // initialization (not hoisted)
b(); // hoist inside b's scope causes an inner a to be modified
alert(a); // alerts 1 since the outer a was never modified
jbabey
  • 45,965
  • 12
  • 71
  • 94
  • 1
    No, the function is really created: http://jsfiddle.net/mwLVD/. The assignment just overwrites the existing symbol with another value. – Felix Kling Sep 05 '12 at 17:59
  • @FelixKling the function `a` is created? i thought only the name is hoisted, not the assignment (does this not happen with functions?) – jbabey Sep 05 '12 at 18:00
  • But it's not an assignment, it's a function **declaration**. `function a() {...}` is different than `a = function() {...}` (and that's exactly the difference). – Felix Kling Sep 05 '12 at 18:01
  • @FelixKling you are right; good to know! "function declaration ('bar' and the function body get hoisted)" [source](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting) – jbabey Sep 05 '12 at 18:01
  • @FelixKling i have edited my answer to reflect this new information. thanks again. – jbabey Sep 05 '12 at 18:03