关于吊装:Javascript中的名称解析?

Name resolution in Javascript?

本问题已经有最佳答案,请猛点这里访问。

我在读这篇文章,我有一些问题,请:

考虑到本规范:

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

这将警告1。(我的问题是为什么?)

文章阐述了它与名称解析的关系。

姓名决议(根据条款)由以下顺序决定:

1
2
3
4
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;.

第3行假设更改全局A的值。但是函数a()…的优先级高于声明内部(如果我理解正确的话)这就是为什么警报1

另外,如果我删除第5行,它将报警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.

我不明白那部分:

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

所以请回答两个问题:

  • 我是否正确理解提醒1的原因

  • 上面这条线是什么意思?(误解部分)

谢谢。


Did I understand correctly the reason for alerting 1

是的

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

这仅仅意味着,虽然已经定义了一个名为a的函数,但a = 10仍将被执行,即在该行之后,a不再指函数,而是指10

我假设他们想稍微放宽前面的语句,避免人们错误地认为,因为函数声明是先执行的,所以分配将不再发生。

函数和变量声明被提升到作用域的顶部。因此代码相当于:

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

function a() {...}在局部范围内创建一个符号(变量)a,它的值是非常相同的函数。下一行,a = 10;,然后为该符号分配一个新值,即一个数字。

1
2
3
4
5
6
7
8
9
10
11
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);


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

上面的例子对你有意义吗?对?很好,那么你就明白了本地范围和全球范围的区别…

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

这个例子对你有意义吗?对?然后,您会理解,在函数中声明变量的位置并不重要,它总是在第一次进入函数时被声明。

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

现在,这个例子有意义吗?对?然后你就会理解动态输入。变量可以被指定为一个函数值,然后可以被一个整数(如10)覆盖。

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

现在,您的示例应该是有意义的,因为我们只是改变了声明a的方式,但它是相同的。


根据我对提升的理解,变量声明和函数声明都被提升。因此,以下是正在发生的事情:

1
2
3
4
5
6
7
8
9
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