9

我认为这myColor可以从sayColor()本地上下文中访问,但即使我在第一次警报后声明 myColor 也不是。为什么?

var myColor = "blue";
function sayColor() {
    alert(myColor); //undefined expected blue
    var myColor = "green";
    alert(myColor); //green
}
sayColor();
4

4 回答 4

17

这里发生的事情称为“提升”。使用var和函数语句的变量声明被“提升”到其包含范围的顶部。(请注意,从 ES6 开始,let语义const有所不同。)因此,在浏览器看来,您的代码实际上如下所示:

var myColor = "blue";
function sayColor() {
    var myColor;
    alert(myColor); //undefined expected blue
    myColor = "green";
    alert(myColor); //green
}
sayColor();

来自MDN

变量的每个定义实际上都是在其作用域顶部的变量声明和在定义所在位置的赋值。

于 2013-07-05T17:29:20.723 回答
7

您正在myColor使用同名的局部变量隐藏全局变量。从函数中删除var关键字以查看全局变量。

var myColor = "blue";
function sayColor() {
    alert(myColor);
    myColor = "green"; // Omit the "var" keyword.
    alert(myColor);
}
sayColor();

Javascript 仅具有函数作用域,并且在函数中声明的所有变量都被提升到顶部,因此它们在整个函数中都可用。OP 原始版本中的第一个警报是使用未初始化的、提升的局部变量,这就是它打印的原因undefined

于 2013-07-05T17:28:06.293 回答
1

您再次在函数内设置变量。浏览器在赋值之前读取函数,这会导致未定义的结果。

这是正确的。

var myColor = "blue";
function sayColor() {
    alert(myColor); //undefined expected blue
    myColor = "green";
    alert(myColor); //green
}
sayColor();
于 2013-07-05T17:29:03.300 回答
1

因为你再次声明它。

 var myColor = "green";

在 JavaScript 中,在解释器执行函数之前,它会扫描整个函数以查找var ...语句。这就是为什么你的 myColor 变量甚至在你的函数的第一条语句执行之前就被重置的原因。

于 2013-07-05T17:29:30.143 回答