了解 Javascript 中的全局和局部范围

Posted

技术标签:

【中文标题】了解 Javascript 中的全局和局部范围【英文标题】:Understanding Global & Local Scope in Javascript 【发布时间】:2012-08-09 22:58:29 【问题描述】:

我一直在使用 Object-Oriented javascript by Stoyan Stefanov 学习 Javascript

他提供了一个比较全局和本地范围的示例:

var a = 123;
function f() 
    alert(a);
    var a = 1;
    alert(a);

f();

看这个例子,我预计第一个警报是“123”,第二个警报是“1”。瞧,斯托扬说:

您可能期望第一个 alert() 将显示 123(值 全局变量 a) 和第二个将显示 1 (本地 a)。 不是这种情况。第一个警报将显示“未定义”。这是 因为在函数内部,局部作用域比 全球范围。因此,局部变量会覆盖任何全局变量 同名。在第一个 alert() 的时候还没有定义 (因此值未定义)但它仍然存在于本地空间中。

我的解释不清楚,局部变量如何覆盖第一个警报中的全局变量?任何其他/不同的解释将不胜感激。

【问题讨论】:

【参考方案1】:

简单来说,首先考虑变量和函数的所有声明。因此,本地var a 实际上只会在本地范围内覆盖全局变量,并且没有任何值,即undefined。所以第一个警报将显示undefined。第二个警报将显示 1,因为它在 a = 1 之后。这只是在本地发生,全局变量 a 的值为 123 - 它不会被更改。

另一个使用函数的例子来展示它是如何工作的

 function show()
    alert("I am global");
 

 function f() 

    show();

    show = function()
       alert("I am second");
      

    show();   

    function show()
        alert("I am first");
    


f();
show();

【讨论】:

我看不出这个例子如何帮助理解变量提升,你甚至没有本地变量。答案中的词语似乎是正确的(虽然令人困惑),但这个例子使这更加令人困惑【参考方案2】:

它没有覆盖全局变量。正在发生的事情称为“变量提升”。也就是说,var a; 被插入到函数的顶部。

脚本引擎将您的脚本更改为以下内容:

var a = 123;
function f() 
    var a;
    alert(a);
    a = 1;
    alert(a);

f();

要学习的课程:始终在使用变量之前声明它们。有人会说在函数顶部声明所有变量。

【讨论】:

谢谢胡安。我猜您会对作者使用“覆盖”一词提出异议?我开始认为如果我在函数之外调用 alert(a) 是用词不当 b/c,我得到“123”,这表明没有覆盖,但有两个“a”变量,一个全局变量和一个局部变量。 Override 不是正确的术语,局部变量 shadows 是全局变量,但真正的问题是要了解,如果您在函数中的任何位置都有 var,全局在整个函数中被隐藏,甚至在它被声明之前。

以上是关于了解 Javascript 中的全局和局部范围的主要内容,如果未能解决你的问题,请参考以下文章

在 C# Web 浏览器中创建 javascript 变量全局范围

JS 变量的作用域

JavaScript有关作用域和预解析

JavaScript中全局变量和局部变量的不同

JavaScript作用域:全局作用域局部作用域块级作用域作用域链变量提升

JavaScript中全局变量和局部变量的不同