JS中关于预编译的【关键知识点】总结
创始人
2024-11-11 21:09:33

在JavaScript中,预编译(hoisting)是指在代码执行之前,JavaScript引擎会首先对代码进行扫描,将所有的变量声明和函数声明提升到代码的最顶部。这一过程使得我们在代码中可以在声明之前使用变量和函数。理解预编译对于深入理解JavaScript的执行机制至关重要。以下是预编译的几个关键知识点:

1. 变量声明提升

JavaScript会将变量声明(var)提升到当前作用域的顶部,但是不会提升变量的赋值。

示例:

console.log(x); // 输出: undefined var x = 5; console.log(x); // 输出: 5 

解释:
在预编译阶段,这段代码实际上变成了:

var x; console.log(x); // 输出: undefined x = 5; console.log(x); // 输出: 5 

因此,在第一次console.log调用时,x已经被声明但未赋值,因此输出undefined

2. 函数声明提升

函数声明会被整体提升到当前作用域的顶部,这意味着函数可以在声明之前被调用。

示例:

hoistedFunction(); // 输出: "This function has been hoisted!"  function hoistedFunction() {     console.log("This function has been hoisted!"); } 

解释:
在预编译阶段,这段代码实际上变成了:

function hoistedFunction() {     console.log("This function has been hoisted!"); }  hoistedFunction(); // 输出: "This function has been hoisted!" 

3. 函数表达式不提升

函数表达式不会被提升,因此在声明之前调用函数表达式会导致错误。

示例:

console.log(notHoisted); // 输出: undefined notHoisted(); // 抛出TypeError: notHoisted is not a function  var notHoisted = function() {     console.log("This function is not hoisted."); }; 

解释:
在预编译阶段,这段代码实际上变成了:

var notHoisted; console.log(notHoisted); // 输出: undefined notHoisted(); // 抛出TypeError: notHoisted is not a function  notHoisted = function() {     console.log("This function is not hoisted."); }; 

由于notHoisted在声明之前被调用,因此它的值是undefined,无法作为函数调用。

4. letconst的特性

letconst声明的变量不会被提升到作用域顶部,但会在声明之前处于暂时性死区(Temporal Dead Zone,TDZ)。

示例:

console.log(a); // ReferenceError: Cannot access 'a' before initialization let a = 3;  console.log(b); // ReferenceError: Cannot access 'b' before initialization const b = 5; 

解释:
letconst的变量在声明之前无法被访问,尝试访问会导致ReferenceError。这与var的行为不同。

5. 预编译过程概述

在代码执行之前,JavaScript引擎会经历以下预编译步骤:

  1. 创建全局执行上下文(Global Execution Context)。
  2. 扫描代码,查找变量声明(var)、函数声明。
  3. 将变量声明提升到当前作用域顶部,并初始化为undefined
  4. 将函数声明提升到当前作用域顶部,并将函数体赋值给对应标识符。
  5. 执行代码。

示例:

function example() {     console.log(a); // 输出: undefined     var a = 2;     console.log(b); // 输出: function b() { console.log("This is function b"); }      function b() {         console.log("This is function b");     } }  example(); 

解释:
在预编译阶段,这段代码实际上变成了:

function example() {     var a;     function b() {         console.log("This is function b");     }      console.log(a); // 输出: undefined     a = 2;     console.log(b); // 输出: function b() { console.log("This is function b"); } }  example(); 

在预编译阶段,ab已经被提升,a初始化为undefinedb初始化为函数体。

结论

预编译是JavaScript执行过程中的一个重要机制,通过理解变量和函数的提升,我们可以更好地理解代码的执行顺序,避免意外的错误。特别是在涉及varletconst以及函数声明和表达式时,预编译机制显得尤为重要。

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...