全局JavaScript变量范围:为什么';这不管用吗?

全局JavaScript变量范围:为什么';这不管用吗?,javascript,scope,Javascript,Scope,所以我在玩JavaScript,遇到了我认为很奇怪的事情。有人能解释一下吗?(我已将警报值作为注释包含在内) 为什么foo()内部的第一个警报(msg)返回的是未定义的,而不是外部的 考虑到这两种方法都很有效: var msg = 'outside'; function foo() { alert(msg); // outside } alert(msg); // outside 以及: 在第一个示例中,msg的声明和初始化被拆分,声明被提升到闭包的顶部 var msg; //decl

所以我在玩JavaScript,遇到了我认为很奇怪的事情。有人能解释一下吗?(我已将警报值作为注释包含在内)

为什么foo()内部的第一个警报(msg)返回的是未定义的,而不是外部的

考虑到这两种方法都很有效:

var msg = 'outside';

function foo() {
  alert(msg); // outside
}

alert(msg); // outside
以及:


在第一个示例中,msg的声明和初始化被拆分,声明被提升到闭包的顶部

var msg; //declaration
msg = "inside" //initialization
因此,您编写的代码与

var msg = 'outside';

function foo() {
var msg;  
alert(msg); // undefined
msg = 'inside';
alert(msg); // inside
}
第二个例子不一样。在第二个示例中,您没有声明局部变量msg,因此alert(msg)引用全局msg。 以下是关于以下内容的进一步解读:

Javascript闭包中的变量声明首先发生,而不管它们位于闭包中的什么位置。因此,在第一个示例中,函数的开头存在一个局部变量
msg
(因为它是在函数中声明的),但直到第一个
警报之后才为其赋值,因此对于第一个警报,
msg
是未定义的

您的第一个示例相当于:

var msg = 'outside';

function foo() {
  var msg;
  alert(msg); // undefined

  msg = 'inside';
  alert(msg); // inside
}

alert(msg); // outside
在第二个示例中,您没有在函数中显式声明
msg
。由于已经存在同名的全局变量,因此使用全局变量而不是定义局部变量

在第三个示例中,您显式声明变量并在尝试使用它之前为其分配一个值,因此当您
alert(msg)
时,本地定义的变量将被警告。

来自:

如果我们在函数中声明但不初始化带有
var
关键字的变量,则该变量在作用域中应该是局部变量,但在整个函数中
未定义的
,直到它[初始化]为止

这将对您有用:

var msg = 'outside';

function foo() {
  alert(window.msg); // outside

  var msg = 'inside';
  alert(msg); // inside
}

alert(msg); // outside
foo();
alert(msg); // still "outside"

var
不是声明。这是一种混淆了许多人的混淆。相反,
var
是一个范围广泛的注释范围内“var”的位置无关紧要。


您可以完全控制java脚本函数的执行,并将变量作为参数传递

在这种情况下,函数内部不能访问外部变量。但如果您想使用传递变量参数来访问函数中的值

var msg = 'outside';

function foo(msg) {
  alert(msg); // outside

  var msg = 'inside';
  alert(msg); // inside
}

foo(msg);    
alert(msg); // outside
选中此项
在另一个变量内g您定义的是一个“私有”变量(在函数范围内),因此其警报值在函数内为“内部”。希望这对你有帮助

你能显示第一个脚本的完整上下文吗?我忘了添加对foo()的调用;但除此之外,这是它的全部背景。我只是在玩变量作用域时遇到了这个问题。没关系,它已经解决了,我怀疑还有其他问题。在同一个作用域级别上,不能有两个同名的变量。考虑到第二个示例可以毫无问题地工作,还有其他信息说明为什么会这样解释吗?对我来说似乎是一样的,只是后面有代码……我也不太清楚为什么我会被否决。无论哪种方式,就像这里出现的其他答案一样,原因是javascript中的变量声明被挂起。这意味着它们被移动到闭包的顶部。@Cory第二个示例中没有
var msg
var
使其成为一个局部变量,而扭曲之处在于,即使在
var
的物理位置之前,它也使其成为局部变量@Shaun啊,明白了!谢谢你的洞察力!不知道var在哪里吊的。很高兴知道。@Shaun当我读到你的帖子时,“var msg;”不在那里,所以我看起来像是胡说八道。
var msg = 'outside';

function foo() {
  alert(window.msg); // outside

  var msg = 'inside';
  alert(msg); // inside
}

alert(msg); // outside
foo();
alert(msg); // still "outside"
var msg = 'outside';

function foo(msg) {
  alert(msg); // outside

  var msg = 'inside';
  alert(msg); // inside
}

foo(msg);    
alert(msg); // outside