我遇到了 JavaScript 的“提升”,但我没有弄清楚这段代码是如何真正起作用的:
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
我知道像 ( function a() {}
) 这样的函数声明将被提升到函数b
范围的顶部,但它不应该覆盖的值a
(因为函数声明覆盖变量声明而不是变量初始化)所以我希望警报的值会是 10 而不是 1!
我遇到了 JavaScript 的“提升”,但我没有弄清楚这段代码是如何真正起作用的:
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
我知道像 ( function a() {}
) 这样的函数声明将被提升到函数b
范围的顶部,但它不应该覆盖的值a
(因为函数声明覆盖变量声明而不是变量初始化)所以我希望警报的值会是 10 而不是 1!
a
设置为1
b()
叫做function a() {}
被提升并创建一个局部变量a
来掩盖全局a
a
设置为10
(覆盖函数a
)a
(仍然1
)被警告这是因为此示例中的编译/解释顺序有些误导。该function a () {}
行在函数的任何其余部分执行之前被解释,所以在函数的最开始,a
它的值是function a () {}
. 当您将其重新分配给 时,您将在 function 的本地范围内10
重新分配值,然后在您返回时将其丢弃,将原始值留在全局范围内。a
b()
a = 1
alert()
您可以通过在适当的地方放置 s 或类似的东西来验证这一点,以查看a
各个点的值是什么。
(1) JavaScript 没有块语句作用域;相反,它将是块所在的代码本地的。
(2) Javascript 在函数范围内声明变量,这意味着在函数中声明的变量在该函数中的任何位置都可用,甚至在它们被赋值之前。
(3) 在函数体内,局部变量优先于同名的全局变量。如果你声明一个与全局变量同名的局部变量或函数参数,你实际上隐藏了全局变量。
你的代码是一样的:(阅读评论)
<script>
var a = 1; //global a = 1
function b() {
a = 10;
var a = 20; //local a = 20
}
b();
alert(a); //global a = 1
</script>
参考:
(1)JavaScript变量作用域:
(2) Javascript提升的危险例子
(3)变量作用域
所以在你的代码中:
var a = 1; //global a = 1
function b() {
a = 10;
return;
function a() {} //local
}
b();
alert(a); //global a = 1
function a(){}
,因此在本地范围内a
创建。a=10
,您设置的是局部变量a
,而不是全局变量。因此,全局变量的值保持不变,你会得到,alerted 1
当我读到你做JavaScript Scoping and Hoisting的同一篇文章时,我也很困惑,因为作者从未展示过这两个开放示例代码在编译器中的解释。
这是您提供的示例,以及页面上的第二个示例:
var a = 1;
function b() {
function a() {} // declares 'a' as a function, which is always local
a = 10;
return;
}
b();
alert(a);
这是页面上的第一个示例:
var foo = 1;
function bar() {
var foo; // a new local 'foo' variable
if (!foo) {
foo = 10;
}
alert(foo);
}
bar();
希望这可以帮助