吊装

什么是吊装?

提升是一种将所有变量和函数声明移动到其范围顶部的机制。但是,变量赋值仍然发生在最初的位置。

例如,请考虑以下代码:

console.log(foo);  // → undefined
var foo = 42;
console.log(foo);  // → 42

以上代码与:

var foo;             // → Hoisted variable declaration
console.log(foo);    // → undefined
foo = 42;            // → variable assignment remains in the same place
console.log(foo);    // → 42

请注意,由于提升上述 undefined 与运行所产生的 not defined 不同:

console.log(foo);    // → foo is not defined 

类似的原则适用于功能。当函数分配给变量(即函数表达式 )时,变量声明将被提升,而赋值保留在同一位置。以下两个代码段是等效的。

console.log(foo(2, 3));     // → foo is not a function

var foo = function(a, b) {
    return a * b;
}
var foo;
console.log(foo(2, 3));     // → foo is not a function
foo = function(a, b) {
    return a * b;
}

声明函数语句时 ,会出现不同的情况。与函数语句不同,函数声明被提升到其作用域的顶部。请考虑以下代码:

console.log(foo(2, 3));  // → 6
function foo(a, b) {
    return a * b;
}

由于提升,上面的代码与下一个代码段相同:

function foo(a, b) {
    return a * b;
}

console.log(foo(2, 3));  // → 6

以下是一些什么是什么,什么不是吊装的例子:

// Valid code:
foo();

function foo() {}

// Invalid code:
bar();                     // → TypeError: bar is not a function
var bar = function () {};

// Valid code:
foo();
function foo() {
    bar();
}
function bar() {}

// Invalid code:
foo();
function foo() {
    bar();                // → TypeError: bar is not a function
}
var bar = function () {};

// (E) valid:
function foo() {
    bar();
}
var bar = function(){};
foo();

吊装的局限性

初始化变量不能是 Hoisted 或简单的 JavaScript Hoists 声明不能初始化。

例如:以下脚本将提供不同的输出。

var x = 2; 
var y = 4; 
alert(x + y);

这将给你 6 的输出。但是……

var x = 2; 
alert(x + y);
var y = 4; 

这将为你提供 NaN 的输出。由于我们正在初始化 y 的值,因此不会发生 JavaScript Hoisting,因此 y 值将是未定义的。JavaScript 将认为 y 尚未声明。

所以第二个例子与下面的例子相同。

var x = 2; 
var y;
alert(x + y);
y = 4; 

这将为你提供 NaN 的输出。

StackOverflow 文档