除了我在同一线程中的 previous answer
添加另一个答案以提供有关吊装的更多详细信息
JavaScript 中的功能,因为之前的答案已被 OP 接受。
首先让我们熟悉一下什么是作用域
JavaScript 中的作用域
对于 JavaScript 初学者来说,最困惑的根源之一是范围。实际上,这不仅仅是初学者。我遇到过很多经验丰富的 JavaScript 程序员,他们并不完全理解作用域。 JavaScript 中范围界定如此混乱的原因是它看起来像 C 系列语言。考虑以下 C 程序:
#include <stdio.h>
int main() {
int x = 1;
printf("%d, ", x); // 1
if (1) {
int x = 2;
printf("%d, ", x); // 2
}
printf("%d\n", x); // 1
}
该程序的输出将是 1、2、1。这是因为 C 和 C 家族的其余部分具有块级范围。当控制进入一个块时,例如 if 语句,可以在该范围内声明新变量,而不会影响外部范围。在 JavaScript 中情况并非如此。在 Firebug 中尝试以下操作:
var x = 1;
console.log(x); // 1
if (true) {
var x = 2;
console.log(x); // 2
}
console.log(x); // 2
在这种情况下,Firebug 将显示 1、2、2。这是因为 JavaScript 具有函数级范围。这与 C 系列完全不同。块,例如 if 语句,不会创建新范围。只有函数会创建新范围。
对于许多习惯于 C、C++、C# 或 Java 等语言的程序员来说,这是出乎意料且不受欢迎的。幸运的是,由于 JavaScript 函数的灵活性,有一种解决方法。如果您必须在函数中创建临时范围,请执行以下操作:
function foo() {
var x = 1;
if (x) {
(function () {
var x = 2;
// some other code
}());
}
// x is still 1.
}
这种方法实际上非常灵活,可以在需要临时作用域的任何地方使用,而不仅仅是在块语句中。但是,我强烈建议您花时间真正理解和欣赏 JavaScript 作用域。它非常强大,也是我最喜欢的语言功能之一。如果您了解范围界定,那么提升对您来说会更有意义。
声明、名称和吊装
在 JavaScript 中,名称以四种基本方式之一进入范围:
Language-defined: 默认情况下,所有作用域都赋予名称 this 和参数。
Formal parameters: 函数可以具有命名形式参数,其作用域为该函数的主体。
- 函数声明:格式为
function foo() {}。
- 变量声明:采用
var foo; 的形式。
-
函数声明和变量声明总是被 JavaScript 解释器以不可见的方式移动(“提升”)到其包含范围的顶部。
- 显然,函数参数和语言定义的名称已经存在。这意味着这样的代码:
例如:
function foo() {
bar();
var x = 1;
}
实际上是这样解释的:
function foo() {
var x;
bar();
x = 1;
}
事实证明,包含声明的行是否会被执行并不重要。以下两个函数是等价的:
function foo() {
if (false) {
var x = 1;
}
return;
var y = 1;
}
function foo() {
var x, y;
if (false) {
x = 1;
}
return;
y = 1;
}
请注意,声明的赋值部分没有被提升。 只吊起名字。这不是函数声明的情况,整个函数体也将被提升。但请记住,声明函数有两种常规方式。考虑以下 JavaScript:
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();
在这种情况下,只有函数声明的主体被提升到顶部。名称“foo”被提升,但主体被留下,在执行期间被分配。
这涵盖了提升的基础知识。此答案的完整 100% 归功于 ben cherry。我不想在我的答案中发布此链接,因为链接可能会断开,我发现此内容非常有用,任何 javascript 开发人员都必须阅读。