JavaScript 提升

摘要:在本教程中,您将学习 JavaScript 提升的概念以及它在幕后的工作原理。

JavaScript 提升简介

当 JavaScript 引擎执行 JavaScript 代码时,它会创建 全局执行上下文。全局执行上下文有两个阶段:

  • 创建
  • 执行

在创建阶段,JavaScript 引擎会将变量和函数声明移至代码的顶部。这被称为 JavaScript 中的提升。

变量提升

变量提升意味着 JavaScript 引擎会将 变量声明 移至脚本的顶部。例如,以下示例声明了 counter 变量并将它的值初始化为 1

console.log(counter); // 👉 undefined
var counter = 1;Code language: JavaScript (javascript)

在这个例子中,我们是在声明之前引用 counter 变量。

然而,第一行代码不会导致错误。原因是 JavaScript 引擎会将变量声明移至脚本的顶部。

从技术上讲,代码在执行阶段看起来像下面这样:

var counter;

console.log(counter); // 👉 undefined
counter = 1;
Code language: JavaScript (javascript)

在全局执行上下文的创建阶段,JavaScript 引擎会将 counter 变量放置在内存中,并将它的值初始化为 undefined

let 关键字

以下代码使用 let 关键字声明 counter 变量:

console.log(counter);
let counter = 1;Code language: JavaScript (javascript)

JavaScript 会发出以下错误:

"ReferenceError: Cannot access 'counter' before initialization

错误消息说明 counter 变量已存在于堆内存中。但是,它还没有被初始化。

在幕后,JavaScript 引擎会提升使用 let 关键字声明的变量声明。但是,它不会初始化 let 变量。

请注意,如果您访问一个不存在的变量,JavaScript 会抛出一个不同的错误:

console.log(alien);
let counter = 1;Code language: JavaScript (javascript)

这是错误信息:

"ReferenceError: alien is not definedCode language: plaintext (plaintext)

函数提升

与变量类似,JavaScript 引擎也会提升 函数 声明。这意味着 JavaScript 引擎也会将函数声明移至脚本的顶部。例如:

let x = 20,
  y = 10;

let result = add(x, y); 
console.log(result); // 👉 30

function add(a, b) {
  return a + b;
}Code language: JavaScript (javascript)

输出

30

在这个例子中,我们在定义 add() 函数之前调用了它。上面代码等效于以下代码:

function add(a, b){
    return a + b;
}

let x = 20,
    y = 10;

let result = add(x,y);
console.log(result); // 👉 30Code language: JavaScript (javascript)

在执行上下文的创建阶段,JavaScript 引擎会将 add() 函数声明放置在堆内存中。更准确地说,JavaScript 引擎会创建一个 Function 类型的对象,以及一个指向该函数对象的函数引用 add

函数表达式

以下示例将 add 从一个普通函数更改为一个函数表达式:

let x = 20,
    y = 10;

let result = add(x,y); // ❌ Uncaught ReferenceError: add is not defined
console.log(result);

let add = function(x, y) {
    return x + y;
}Code language: JavaScript (javascript)

如果您执行代码,将会发生以下错误:

Uncaught ReferenceError: add is not definedCode language: plaintext (plaintext)

在全局执行上下文的创建阶段,JavaScript 引擎会在内存中创建 add 变量,并将它的值初始化为 undefined

在执行以下代码时,addundefined,因此它不是一个函数:

let result = add(x,y);Code language: JavaScript (javascript)

add 变量仅在全局执行上下文的执行阶段被赋值为一个 匿名函数

箭头函数

以下示例将 add 函数表达式更改为 箭头函数

let x = 20,
    y = 10;

let result = add(x,y); // ❌ Uncaught ReferenceError: add is not defined
console.log(result);

let add = (x, y) => x + y; Code language: JavaScript (javascript)

该代码也会发出与函数表达式示例相同的错误,因为箭头函数是定义函数表达式的语法糖。

Uncaught ReferenceError: add is not definedCode language: plaintext (plaintext)

与函数表达式类似,箭头函数不会被提升。

总结

  • JavaScript 提升发生在执行上下文的创建阶段,将变量和函数声明移至脚本的顶部。
  • JavaScript 引擎会提升使用 let 关键字声明的变量,但它不会像使用 var 关键字声明的变量那样初始化它们。
  • JavaScript 引擎不会提升函数表达式和箭头函数。
本教程对您有帮助吗?