Hoisting(变量提升)是 JavaScript 中的一种行为,它在编译阶段将变量和函数声明提升到其所在作用域的顶部。这意味着,无论声明出现在代码的哪个位置,它们都被实际上移动到其所在作用域的顶部,使其能够在代码中实际放置之前就可以使用。
让我们看一下下面的代码,并思考它的输出。
代码语言:javascript复制console.log(notEqual(1, '1')); // => false
// 函数声明
function notEqual(item1, item2) {
return item1 === item2;
}
我们能够在声明函数之前就使用 notEqual
函数。这就是 JavaScript 中 hoisting 的魔力。
这段代码正常工作是因为 notEqual()
通过函数声明创建,并被提升到作用域的顶部。
好的,再来看一个例子并猜测它的输出。
代码语言:javascript复制console.log(name);
var name = "John";
这段代码的输出是 undefined,不会出错,也不会抛出错误,也不会打印赋给 name
变量的值 'John'
。
让我们理解 JavaScript 的这种行为。
Hoisting 影响变量的生命周期,包括 3 个步骤:
声明 - 创建一个新的变量。
初始化 - 用一个值初始化变量。
使用 - 访问和使用变量的值。
声明 –> 初始化/赋值 –> 使用
代码语言:javascript复制// 声明
var name;
// 初始化
name = 'John';
// 使用
console.log(name); // => John
Hoisting 将变量和函数声明移动到函数作用域的顶部(如果在任何函数外,则为全局作用域)。
因此,在这段代码 console.log(name); var name = "John";
中,只有声明 var name
被移动到作用域的顶部。
var name
的默认值是 undefined。
实际上,Hoisting 最初是为函数而创建的,它对 var
的适用性只是副产品。
变量 name
的 hoisting 带有 let
和 const
使用 let
和 const
声明的变量会被 hoist,但不会被初始化为默认值。在声明之前访问 let
或 const
变量会导致 ReferenceError:
function learnHoisting(value) {
if (value) {
//name 进入了临时死区
console.log(name); // Throws ReferenceError: name is not defined
let name = 'foo';
// name 的临时死区结束
console.log(name); // => 'foo'
return true;
}
return false;
}
learnHoisting(1)
解释器仍然会 hoist name
:错误消息告诉我们变量在某处被初始化。
注意 - 从声明语句到块的开始,let
和 const
变量处于一个临时死区(TDZ),无法被访问。
我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!