10

下面的代码是 JavaScript 代码。我正在尝试了解 JavaScript 中的函数范围,并在此处关注文章。我正在复制下面的代码 -

var cow = "purple"; // just a random cow

var f = function (x) {
    var r = 0;
    cow = "glue";
    if (x > 3) {
        var cow = 1; // a local variable
        r = 7;
    }
    return r;
};

var z = f(2);
alert(cow); // returns purple

我不太明白为什么会提示字符串“purple”。该行cow = "glue";应该将 cow 变量的值设置为“glue”。如果我删除 if 块,然后在最后一个语句中警告 cow,我会看到字符串“glue”被警告。

调用 f(2) 时,没有输入 if 代码块,也没有执行其中的任何内容,那么为什么我会看到不同的结果?即为什么最后一条语句中的alerting cow 现在返回字符串“purple”?

4

4 回答 4

9

函数内部的变量声明总是被提升到顶部。所以你的代码实际上是:

var f = function (x) {
    var cow, r;
    r = 0;
    cow = "glue";
    if (x > 3) {
        cow = 1; // a local variable
        r = 7;
    }
    return r;
};

在函数内部,您总是分配给本地 cow,而不是全局。

于 2013-06-12T19:08:26.397 回答
5

这里要理解的两件事是 Javascript 变量被提升到其作用域的顶部,并且 javascript 没有块作用域。

所以

  1. 范围内的所有变量都被认为是在范围的开头声明的
  2. if 语句不会创建新范围。

所以你的例子相当于

var cow = "purple"; // just a random cow

var f = function (x) {
    var cow, r = 0;
    cow = "glue";
    if (x > 3) {
        cow = 1; // a local variable
        r = 7;
    }
    return r;
};

var z = f(2);
alert(cow); // returns purple

if 语句中的 var 声明被提升到顶部。此时,函数内的所有奶牛引用都指向局部变量奶牛,而不是来自外部范围的奶牛。

于 2013-06-12T19:09:04.230 回答
4

Javascript 没有块范围(catch块除外)。
所有var语句都被提升到包含函数的顶部。

因此,cow指的是函数中任何地方的局部变量,即使if永远不会执行。

于 2013-06-12T19:08:15.170 回答
4

你没有真正读过那篇文章,是吗?它明确指出

打电话时cow会变成吗?不,在上面的代码中是安全的,因为if 块内声明适用于整个 function。这意味着它是整个函数的局部变量。"glue"f(2)cowvar cowcow

但是,当您删除 if 块时,您也会删除其中的变量声明,并且赋值将针对全局变量。

于 2013-06-12T19:19:52.267 回答