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.

有帮助吗?

解决方案

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);

其他提示

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.

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top