-2

也许这很愚蠢,但我真的对'var'关键字感到沮丧。我很难弄清楚以下问题:

var local = true;
function outer() {
    /* local scope */
    var local = false;
    function inner() {
      alert(local);
      var local;
    }
    inner();
}
outer();

function a(x) {
    return x * 2;
}
var a;
alert(a);

任何解释表示赞赏。

4

1 回答 1

2

带注释的来源;我假设这段代码从全局范围开始:

var local = true;      // Creates a global variable called `local`
function outer() {
    /* local scope */
    var local = false; // Creates a local `local` within `outer`, shadowing (hiding) the global
    function inner() {
      alert(local);    // alerts "undefined", the value of `inner`'s `local`
      var local;       // Creates a local `local` within `inner`, shadowing (hiding) `outer`'s version
    }
    inner();
}
outer();

function a(x) {        // Creates a global function `a`
    return x * 2;
}
var a;                 // Has no effect
alert(a);              // alerts the function source (on engines that have it)

上面的代码中基本上有三件事在起作用:

  1. 嵌套范围内的声明会隐藏(隐藏)包含范围内的声明。所以localin outershadows the global 和localin innershadows outer's local

  2. var声明在执行进入执行上下文时被处理,而不是它们出现在源代码中的位置。它们有时被称为“提升”,因为它们被有效地向上移动(提升、提升)到它们发生的上下文的顶部。(更多:糟糕的误解var)这种效果在函数中特别明显inner,因为local被警告的是 from inner,而不是 from outer(这就是它的原因undefined),即使声明位于警报下方。

  3. 函数声明在定义它们的范围内创建一个符号,在与var声明相同的符号空间中。(具体来说,它们都在它们发生的执行上下文词法环境的绑定对象中创建条目。)因此,如果您有一个函数声明和具有相同名称的 a (就像您在代码末尾所做的那样) ,有冲突。哪个赢?函数声明获胜,因为规范 §10.5规定的顺序,它说函数声明发生在声明之前,并且已经定义的符号的 a 不会覆盖它。varavarvar

于 2013-07-15T06:45:23.733 回答