3

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

考虑到这段代码:

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

这会提醒 1. (我的问题是为什么?)

文章说明了它与名称解析有关。

名称解析(根据文章)由以下顺序确定:

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

ps如果我删除第5行,它会提醒10。

一般来说,如果一个名字已经被定义,它永远不会被另一个同名的实体重新定义。即函数声明优先于同名变量的声明。但这并不意味着变量赋值不会替换函数,只是它的定义会被忽略。

我不明白那部分:

但这并不意味着变量赋值的值不会替换函数

所以有两个问题:

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

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

谢谢。

4

3 回答 3

7

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

是的

“但这并不意味着变量赋值不会替换函数”
上面这行是什么意思?(被误解的部分)

它只是意味着虽然a已经定义了一个具有名称的函数,但a = 10仍将被执行,即在该行之后a不再引用函数而是指向10.

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


函数和变量声明被提升到作用域的顶部。所以代码等价于:

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;然后为该符号分配一个新值,即一个数字。

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);
于 2012-09-05T17:53:30.140 回答
3
var a = 1;
function b () {
    var a = 10;
}
b();
alert(a);

上面的例子对你有意义吗?是的?好的,那么您了解本地范围和全局范围之间的区别...

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

这个例子对你有意义吗?是的?然后你就会明白,在函数中声明变量的位置无关紧要,它总是在第一次进入函数时声明。

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

现在,这个例子有意义吗?是的?然后你就理解了动态类型。一个变量可以被赋予一个函数作为一个值,然后可以被一个整数覆盖,比如 10。

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

现在你的例子应该是有意义的,因为我们只是改变了我们声明 a 的方式,但它是一样的。

于 2012-09-05T18:06:26.100 回答
2

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

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
于 2012-09-05T17:57:59.663 回答