我遇到了 JavaScript 'hoisting',但我没有弄清楚这段代码是如何真正起作用的:
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
我知道像 ( function a() {}
)这样的函数声明将被提升到函数b
作用域的顶部,但它不应该覆盖的值a
(因为函数声明覆盖变量声明而不是变量初始化)所以我预计警报的值会是 10 而不是 1!!
我遇到了 JavaScript 'hoisting',但我没有弄清楚这段代码是如何真正起作用的:
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 () {}
。当您将其重新分配给 时10
,您正在重新分配a
function 局部范围内的值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
,而不是全局变量。因此,全局变量的值保持不变,您会收到警报 1
当我读到你做JavaScript Scopeing 和 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();
希望这可以帮助