【问题标题】:Understanding JavaScript function scoping了解 JavaScript 函数作用域
【发布时间】:2013-06-12 19:05:43
【问题描述】:

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

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 块,然后在最后一个语句中警告牛,我会看到字符串“glue”被警告。

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

【问题讨论】:

    标签: javascript scope


    【解决方案1】:

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

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

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

    【讨论】:

    • 我想你的意思是var cow,r,而不是var f,r
    • @ben336 是的,我刚刚修复了这个问题。也许您的浏览器没有收到编辑通知? websocket的事情有时会失败......
    • 是的,现在看到它。今天使用参差不齐的网络连接。在我发布我的帖子之前,也没有看到其他人已经回答。
    【解决方案2】:

    这里要理解的两件事是 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 声明被提升到顶部。此时,函数内的所有奶牛引用都指向局部变量奶牛,而不是外部作用域中的奶牛。

    【讨论】:

    • 教程中cow=glue前面没有var,不知道是不是作者的错误
    • 不,它不一定是错误,如果重点是展示 js 作用域的工作原理。在 if 语句中声明 var 是不好的做法,因为它令人困惑,但它不是“错误”
    • +1 指出 if 块不会创建新范围,这很可能是 OP 误解的根源。
    • @bfavaretto 哎呀。我什至不能把这归咎于 websockets :)
    • 区块范围即将推出。请参阅 JS 'let' 关键字。不过老实说,我从来没有错过它。
    【解决方案3】:

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

    因此,cow 引用函数中任意位置的局部变量,即使 if 从未执行。

    【讨论】:

    【解决方案4】:

    您并没有真正阅读那篇文章,是吗?它明确指出

    当您调用 f(2) 时,cow 是否会变成 "glue"?不,cow 在上述代码中是安全的,因为 if 块内的 var cow 声明适用于整个函数。也就是说cow是整个函数的局部变量。

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

    【讨论】:

      猜你喜欢
      • 2018-04-01
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 2011-03-11
      • 2015-04-19
      • 1970-01-01
      相关资源
      最近更新 更多