我正在读一些关于Variable Hoisting我无法理解如何学习它的东西.我读了W3C学校的解释.但是,根据示例代码,我无法做出什么是悬挂.
代码1 [这是来自w3c学校的代码]
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var x = 5; // Initialize x
var y; // Declare y
elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y; // Display x and y
y = 7; // Assign 7 to y
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
但上面的代码仍然显示'undefined'变量y.
如果我更改代码如下,那么它工作正常.但是,下面的代码是常见的,而不是要理解的不同代码'hoisting'
<script>
var x = 5; // Initialize x
var y;
y = 7;
elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y; // Display x and y
</script>
Run Code Online (Sandbox Code Playgroud)
有什么帮助可以理解'变量提升'吗?
(注:我添加ES2015的简要讨论let,并const在此答案的结束.)
从根本上说,变量提升意味着无论你var在任何给定的范围内看到什么,它就好像它是在范围的最开始.所以这些都是相同的:
function foo() {
var a = 42;
}
function foo() {
var a;
a = 42;
}
function foo() {
a = 42;
var a;
}
function foo() {
var a;
a = 42;
var a;
}
Run Code Online (Sandbox Code Playgroud)
它们由JavaScript引擎处理,就像它们一样:
function foo() {
var a;
a = 42;
}
Run Code Online (Sandbox Code Playgroud)
这是一个实际使用变量提升的例子,并举一个我称之为隐形全球恐怖 的例子(这是我贫血的小博客上的帖子):
function foo() {
a = 42;
b = 67;
console.log(a); // 42
console.log(b); // 67
var a;
}
foo();
console.log(typeof a); // undefined
console.log(typeof b); // number?!
console.log(b); // 67?!Run Code Online (Sandbox Code Playgroud)
为什么b存在于外面foo?因为在内部foo,这两行做了很多不同的事情:
a = 42;
b = 67;
Run Code Online (Sandbox Code Playgroud)
第一行设置局部变量a,因为我们声明了它.是的,我们稍后宣布,但我们宣布了.
第二行创建一个隐式全局变量b,因为我们从未b在任何地方声明过foo.
更多(在我的博客上):
ES2015(又名"ES6")介绍let和const.它们的处理方式略有不同var:
undefined只有在逐步执行代码时达到声明时,才会初始化它们(使用或提供的值).示范点#1(块范围):
function foo() {
{
let a = 1;
console.log(a); // 1
}
console.log(a); // ReferenceError: a is not defined
}
foo();
Run Code Online (Sandbox Code Playgroud)
演示第2点:这可以使用var,它不适用于let:
function foo() {
a = 42; // ReferenceError: a is not defined
let a;
}
foo();
Run Code Online (Sandbox Code Playgroud)
保留标识符(声明)和何时可以使用它(初始化)之间的时间称为Temporal Dead Zone,在此期间您无法使用该变量.