变量提升

2023-12-12 00:42:56 浏览数 (1)

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 带有 letconst

使用 letconst 声明的变量会被 hoist,但不会被初始化为默认值。在声明之前访问 letconst 变量会导致 ReferenceError:

代码语言:javascript复制
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:错误消息告诉我们变量在某处被初始化。

注意 - 从声明语句到块的开始,letconst 变量处于一个临时死区(TDZ),无法被访问。

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

0 人点赞