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

时间:2010-04-21 18:03:35

标签: javascript scope

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

为什么foo()中的第一个警报(msg)返回未定义而不是之外?

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 个答案:

答案 0 :(得分:17)

你的第一个例子中发生的事情是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)引用全局消息。 以下是对此的进一步阅读: Hoisting

答案 1 :(得分:3)

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

你的第一个例子相当于:

msg

在第二个示例中,您未在函数中明确声明var msg = 'outside'; function foo() { var msg; alert(msg); // undefined msg = 'inside'; alert(msg); // inside } alert(msg); // outside 。由于已经存在具有相同名称的全局变量,因此使用全局变量而不是定义的本地变量。

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

答案 2 :(得分:2)

来自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"

答案 3 :(得分:1)

var不是声明。混淆了许多人是一种混乱。相反,var范围范围的注释。 在范围内放置'var'并不重要。

var in JavaScript is an Annotation, not Statement

答案 4 :(得分:1)

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

此处案例函数中无法访问外部变量。但是如果你想使用传递变量参数来访问函数内的那个值。

var msg = 'outside';

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

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

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

检查此 Demo jsFiddle

在另一个变量中 g你定义的是一个私人'变量(在功能范围中)所以它的警报"内部"功能内的价值。希望这能帮到你!