JavaScript本地和全局变量混淆

104

我是JavaScript的新手,我正在练习本地和全局变量作用域。以下是我的代码(fiddle):

var myname = "initial"
function c(){
    alert(myname);
    var myname = "changed";
    alert(myname);
}
c();

当第一个警报被调用时,它显示myname为未定义。所以我很困惑,为什么我不能访问全局实例myname,如果我不在函数内定义myname,那么它将正常工作。

2
如果您执行 **alert(window.myname);**,那么您将获得值。 - Just code
@dholakiyaankit 我已经尝试使用 window.myname,但它仍然显示未定义... - Bharat Soni
@BharatSoni 在我的浏览器中window.myname是有效的。 - EmptyArsenal
它应该能够工作,巴拉特。 - Just code
2
变量var myname = "initial"不是全局变量,它只能从当前作用域中的javascript访问。如果要声明全局变量,请不使用"var"关键字,并且该变量应该是window对象的属性。 - llouk
显示剩余4条评论
2个回答

61

在JavaScript中,变量声明会自动移到函数的顶部。因此,解释器会使其看起来更像这样:

var myname = "initial"
function c(){
    var myname;
    // Alerts undefined
    alert(myname);
    myname = "changed";
    // Alerts changed
    alert(myname);
}
c();

这被称为变量提升

由于变量提升和任何变量的作用域都是其声明所在的函数,因此通常建议在函数顶部列出所有变量,以避免混淆。


我已经理解了,所以无法访问与局部变量同名的全局变量。?? - Bharat Soni
2
你应该能够通过 window.myname 来访问它。请参见此处:https://dev59.com/YXDYa4cB1Zd3GeqPBo0a 但是,全局变量通常不被认为是一种良好的实践,在大多数情况下最好定义一个全局对象,并通过该对象访问它。例如 var me = { myname: "initial" },然后在函数中调用 me.myname - EmptyArsenal
1
声明变量被提到了最上面是不正确的说法。例如,如果在第10行写上var myname =“initial”,那么我们看到的结果并不像第1行上的var myname =“initial”,实际上我们看到的行为就好像 var myname 在第1行上,并且在第10行上被赋予了值,即myname =“initial”。 - user2603796
另外,请注意,在函数外部使用 var myVariable 并不会自动将其变为全局变量。通常,如果在前面没有任何内容声明 myVariable,它就会成为全局变量(除非在函数中已经有作用域/设置)。但是最好在这样做时使用 window.。再说了,尽可能避免使用全局变量 :P - redfox05

9

它并没有替换全局变量。发生的是“变量提升”。也就是说,var myname;会被插入到函数顶部。在使用变量之前,请始终对其进行初始化。

尝试这样做:

var myname = "initial";

function c() {
    alert(myname);
    myname = "changed";
    alert(myname);
}

c();


先生,我不仅仅是想改变这个值...你所做的是直接改变全局变量的值本身...我想要理解这种情况发生的原因。 - Bharat Soni
这解决了警告未定义的问题,但它消除了任何本地变量,因为它仅使用全局变量 myname - EmptyArsenal
它并不是替换全局变量。发生的情况被称为“变量提升”。也就是说,myname var myname;会被插入到函数顶部。在使用变量之前始终要初始化你的变量,你可以参考这个链接:https://dev59.com/KGct5IYBdhLWcg3wpO7H?rq=1 - Sridhar R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接