全局 JavaScript 变量范围:为什么这不起作用?

IT技术 javascript scope
2021-03-06 20:40:58

所以我在玩 JavaScript 并遇到了我认为很奇怪的事情。有没有人能够解释以下内容?(我已将警报值包含在评论中)

为什么 foo() 内部的第一个 alert(msg) 返回undefined而不是外部

var msg = 'outside';

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

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

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

考虑到这些都可以正常工作:

var msg = 'outside';

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

alert(msg); // outside

和:

var msg = 'outside';

function foo() {
  var msg = 'inside';
  alert(msg); // inside
}

alert(msg); // outside
5个回答

在你的第一个例子中发生的事情是 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。这是一些进一步的阅读: 吊装

@Shaun 啊,明白了!感谢您的洞察力!不知道 var 在哪里悬挂。很高兴知道。
2021-04-18 20:40:58
@Shaun 当我读完你的帖子“var msg;” 不在那里,所以我看起来像废话。
2021-04-19 20:40:58
考虑到第二个示例工作没有问题,有关为什么以这种方式解释的任何其他信息?对我来说似乎一样,只是它后面有代码......
2021-04-21 20:40:58
@Cory 第二个例子中没有var msgvar使其成为一个局部变量,扭转是它甚至使得它如此的物理位置var
2021-05-10 20:40:58
我也不太确定为什么我得到了反对票。无论哪种方式,就像这里出现的其他答案一样,原因是 javascript 中的变量声明被提升。这意味着它们被移动到闭合的顶部。
2021-05-11 20:40:58

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

你的第一个例子相当于:

var msg = 'outside';

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

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

alert(msg); // outside

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

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

来自http://www.irt.org/script/1321.htm

如果我们var在函数内使用关键字声明但未初始化变量,则它应该在范围内是局部的,但undefined在整个函数中直到它被[初始化]...

这对你有用:

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' 在范围内的位置无关紧要。

JavaScript 中的 var 是注解,而不是语句

您可以完全控制执行Java脚本功能,并传递变量作为自变量,

在这种情况下,函数内部无法访问外部变量但是如果你想使用你传递变量参数来访问函数内部的那个值。

var msg = 'outside';

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

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

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

检查这个 Demo jsFiddle

里面的另一个变量定义g是一个“私人”变量(在一个函数范围内),所以它警告“内部”函数中的value。希望这对你有帮助!