如何详细了解JavaScript的预编译全过程?

2026-04-27 16:121阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2278个文字,预计阅读时间需要10分钟。

如何详细了解JavaScript的预编译全过程?

本篇文章为家长带来了关于JavaScript中预编译的相关知识,主要通过实例介绍预编译的相关问题,希望对家长有所帮助。

阶段(三个)

一、预编译的概念预编译是JavaScript在执行代码前进行的一项操作,它主要包括变量的声明和函数的声明。预编译的目的是为了优化代码的执行效率。

二、预编译的实例以下是一个预编译的实例:

javascriptconsole.log(a); // 输出:undefinedvar a=1;console.log(b); // 报错:b is not definedfunction fn() { console.log(c); // 输出:undefined var c=2;}fn();

在这个例子中,变量`a`在声明后立即初始化,所以`console.log(a)`输出`undefined`。而变量`b`没有初始化,所以`console.log(b)`会报错。函数`fn`在调用时,`c`变量也被预编译,因此`console.log(c)`输出`undefined`。

三、预编译的相关问题

1.预编译会影响代码的执行顺序。

2.预编译过程中,变量的声明会提升到函数的最前面。

3.函数的声明会先于变量的声明进行预编译。

词汇法分析

词汇法分析(Lexical Analysis)是程序设计语言处理的第一步,它将源代码中的字符序列转换成一系列的标记(Token)。在JavaScript中,词汇法分析的主要任务包括:

1. 识别变量名、函数名、关键字等。

2.识别运算符、分隔符等。

3.识别注释和空白符。

词汇法分析是理解预编译过程的基础,它确保了代码的每个部分都能被正确地识别和处理。

如何详细了解JavaScript的预编译全过程?

本篇文章给大家带来了关于javascript中预编译的相关知识,其中主要通过示例来介绍预编译的相关问题,希望对大家有帮助。

阶段(三个)
  1. 词法语法分析:词法语法分析就是检查JavaScript代码是否有一些低级的语法错误
  2. 预编译:本文主讲
  3. 执行代码:执行代码就是js引擎解析代码,解析一行执行一行

这章主要讲预编译过程

预编译过程

预编译也分为2个时间点:

  1. 第一个是在JavaScript代码执行之前
  2. 第二个是在函数执行之前。

但是JavaScript代码之前,之前的预编译只发生一次,函数执行之前的预编译是多次的。

1. JavaScript代码执行之前的预编译
  1. JavaScript代码执行之前,首先会创建一个全局对象,可以理解为window对象,也可以理解为GOGlobal Object)对象,我们是看不到的(无法打印)
  2. 然后将所有声明的全局变量未使用varlet声明的变量放到GO对象中,并且赋值为undefined(联想到“变量提升”)
  3. 分析**函数声明:**然后再将所有的函数声明也放到GO对象中,并且赋值为函数自身的函数体(函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖)
案例说明

<script> var a = 1; console.log(a); console.log(b); var b = 10; function fun (a) { console.log(b); var a = b = 2; var c = 123; console.log(a); console.log(b); } var a2 = 20 fun(1); </script>

结合上面说的步骤:

  1. 首先,<script></script>中的代码执行之前会创建一个GO对象(window对象)

    GO = { //自带的属性都不写 }

  2. 将所有声明的全局变量、未使用varlet声明的变量放到GO对象中,并且赋值为undefined

    GO = { a : undefined, b : undefined, a2 : undefined }

  3. 分析函数声明,函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖

    GO = { a : undefined, b : undefined, a2 : undefined, function fun (a) { var a = b = 2; var c = 123; } }

  4. 此时完成了js代码执行之前的预编译过程,开始执行js代码,首先是给a进行赋值为1,在GO对象里边也会进行对应的改变:

    GO = { a : 1, b : undefined, a2 : undefined, function fun (a) { var a = b = 2; var c = 123; } }

  5. 然后打印a,此时会在GO对象上去找变量a,然后此时的a的值为1,所以console.log(a) 是等于1的。接着打印b,也会去GO对象上找,找到了b的值为undefined,所以console.log(b)是等于undefined

  6. 接着执行到赋值语句:b = 10; 此时GO对象里b的值变成了10

    GO = { a : 1, b : 10, a2 : undefined, function fun (a) { var a = b = 2; var c = 123; } }

  7. 接着下一行代码是一个**fun函数,此时不会去执行该函数**,因为在前面的预编译过程中实际上是被放到了代码的最前端,就是传说中的声明提前,所以忽略掉了。接着给a2进行赋值操作a2 = 20,GO对象也发生变化:

    GO = { a : 1, b : 10, a2 : 20, function fun (a) { var a = b = 2; var c = 123; } }

  8. 接着是执行fun函数,如上面说到的另外一个时间点发生的预编译,就是执行函数之前,现在就来说一下函数执行前的预编译是怎么样的。

2. 函数执行前的预编译
  1. 函数调用,也是会生成自己的作用域(**AO:**Activetion Object,执行期上下文)AO活动对象。函数调用时候,执行前的一瞬间产生的,如果有多个函数的调用,会产生多个AO

    1. 生成AO对象:函数执行前的一瞬间,生成AO活动对象
    2. 分析生成AO属性:查找形参变量声明放到AO对象,赋值为undefined
    3. 分析函数声明:查找函数声明放到AO对象并赋值为函数体。函数名为属性名,值为函数体;

    如果遇到AO对象上属性同名,则无情覆盖

  2. 逐行执行。

案例说明

拿的是上文中的代码示例。

  1. 第一步创建AO对象

    AO{ }

  2. 查找形参变量声明放到AO对象并赋值为undefined

    注意:fun函数里边的b是未经var声明的,所以是全局变量,不会被放在fun的AO上。

    AO{ a: undefined,//形参a与局部变量a同名 c: undefined }

  3. 实参赋值到形参

    AO{ a: 1, c: undefined, }

  4. 查找函数声明放到AO对象并赋值为函数体,fun函数没有函数声明,所以忽略这一步。

  5. 函数执行之前的预编译完成,开始执行语句

  6. 执行代码

    1. 首先执行打印变量b,而此时fun的AO里边并没有变量b,所以会去GO对象里边找,此时的GO对象b的值为10,所以第一行代码打印出10;

    2. 第二行代码首先要看的是b = 2,然后GO对象里边b的值就被改为2了。

      GO = { a : 1, b : 10, a2 : 20, function fun (a) { var a = b = 2; var c = 123; } }

    3. 然后b再赋值给a,变量a是属于局部变量a,所以fun的AO对象里边a的值被改为2。

      AO{ a: 2, c: undefined, }

    4. 接着下一个赋值语句是c = 123,所以AO对象中c的值被改为了123

      AO{ a: 2, c: 123, }

    5. 此时再执行console.log(a)的值就是AO对象里边a的值 2;执行console.log(b)的值就是GO对象b的值 2,至此函数fun执行完毕,紧跟着fun的AO也会被销毁

  7. 综上所述,依次打印出来的值为:1,undefined,10,2,2

总结预编译两个小规则:
  1. 函数声明整体提升(无论函数调用和声明的位置是前是后,系统总会把函数声明移到调用前面)
  2. 变量声明提升(无论变量调用和声明的位置是前是后,系统总会把声明移到调用前,注意仅仅只是声明,所以值是undefined
预编译前奏
  1. imply global(暗示全局变量-专业术语) 即:任何变量,如果未经声明就赋值,则此变量就位全局变量所有。(全局域就是window,这里再一次说明了JavaScript是基于对象的语言,base on window)
  2. 一切声明的全局变量,全是window的属性;var a=12;等同于window.a = 12;(会造成window这个对象特别臃肿)
  3. 函数预编译发生在函数执行前一刻(懒加载机制)

相关推荐:javascript学习教程、web前端开发视频教程

本文共计2278个文字,预计阅读时间需要10分钟。

如何详细了解JavaScript的预编译全过程?

本篇文章为家长带来了关于JavaScript中预编译的相关知识,主要通过实例介绍预编译的相关问题,希望对家长有所帮助。

阶段(三个)

一、预编译的概念预编译是JavaScript在执行代码前进行的一项操作,它主要包括变量的声明和函数的声明。预编译的目的是为了优化代码的执行效率。

二、预编译的实例以下是一个预编译的实例:

javascriptconsole.log(a); // 输出:undefinedvar a=1;console.log(b); // 报错:b is not definedfunction fn() { console.log(c); // 输出:undefined var c=2;}fn();

在这个例子中,变量`a`在声明后立即初始化,所以`console.log(a)`输出`undefined`。而变量`b`没有初始化,所以`console.log(b)`会报错。函数`fn`在调用时,`c`变量也被预编译,因此`console.log(c)`输出`undefined`。

三、预编译的相关问题

1.预编译会影响代码的执行顺序。

2.预编译过程中,变量的声明会提升到函数的最前面。

3.函数的声明会先于变量的声明进行预编译。

词汇法分析

词汇法分析(Lexical Analysis)是程序设计语言处理的第一步,它将源代码中的字符序列转换成一系列的标记(Token)。在JavaScript中,词汇法分析的主要任务包括:

1. 识别变量名、函数名、关键字等。

2.识别运算符、分隔符等。

3.识别注释和空白符。

词汇法分析是理解预编译过程的基础,它确保了代码的每个部分都能被正确地识别和处理。

如何详细了解JavaScript的预编译全过程?

本篇文章给大家带来了关于javascript中预编译的相关知识,其中主要通过示例来介绍预编译的相关问题,希望对大家有帮助。

阶段(三个)
  1. 词法语法分析:词法语法分析就是检查JavaScript代码是否有一些低级的语法错误
  2. 预编译:本文主讲
  3. 执行代码:执行代码就是js引擎解析代码,解析一行执行一行

这章主要讲预编译过程

预编译过程

预编译也分为2个时间点:

  1. 第一个是在JavaScript代码执行之前
  2. 第二个是在函数执行之前。

但是JavaScript代码之前,之前的预编译只发生一次,函数执行之前的预编译是多次的。

1. JavaScript代码执行之前的预编译
  1. JavaScript代码执行之前,首先会创建一个全局对象,可以理解为window对象,也可以理解为GOGlobal Object)对象,我们是看不到的(无法打印)
  2. 然后将所有声明的全局变量未使用varlet声明的变量放到GO对象中,并且赋值为undefined(联想到“变量提升”)
  3. 分析**函数声明:**然后再将所有的函数声明也放到GO对象中,并且赋值为函数自身的函数体(函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖)
案例说明

<script> var a = 1; console.log(a); console.log(b); var b = 10; function fun (a) { console.log(b); var a = b = 2; var c = 123; console.log(a); console.log(b); } var a2 = 20 fun(1); </script>

结合上面说的步骤:

  1. 首先,<script></script>中的代码执行之前会创建一个GO对象(window对象)

    GO = { //自带的属性都不写 }

  2. 将所有声明的全局变量、未使用varlet声明的变量放到GO对象中,并且赋值为undefined

    GO = { a : undefined, b : undefined, a2 : undefined }

  3. 分析函数声明,函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖

    GO = { a : undefined, b : undefined, a2 : undefined, function fun (a) { var a = b = 2; var c = 123; } }

  4. 此时完成了js代码执行之前的预编译过程,开始执行js代码,首先是给a进行赋值为1,在GO对象里边也会进行对应的改变:

    GO = { a : 1, b : undefined, a2 : undefined, function fun (a) { var a = b = 2; var c = 123; } }

  5. 然后打印a,此时会在GO对象上去找变量a,然后此时的a的值为1,所以console.log(a) 是等于1的。接着打印b,也会去GO对象上找,找到了b的值为undefined,所以console.log(b)是等于undefined

  6. 接着执行到赋值语句:b = 10; 此时GO对象里b的值变成了10

    GO = { a : 1, b : 10, a2 : undefined, function fun (a) { var a = b = 2; var c = 123; } }

  7. 接着下一行代码是一个**fun函数,此时不会去执行该函数**,因为在前面的预编译过程中实际上是被放到了代码的最前端,就是传说中的声明提前,所以忽略掉了。接着给a2进行赋值操作a2 = 20,GO对象也发生变化:

    GO = { a : 1, b : 10, a2 : 20, function fun (a) { var a = b = 2; var c = 123; } }

  8. 接着是执行fun函数,如上面说到的另外一个时间点发生的预编译,就是执行函数之前,现在就来说一下函数执行前的预编译是怎么样的。

2. 函数执行前的预编译
  1. 函数调用,也是会生成自己的作用域(**AO:**Activetion Object,执行期上下文)AO活动对象。函数调用时候,执行前的一瞬间产生的,如果有多个函数的调用,会产生多个AO

    1. 生成AO对象:函数执行前的一瞬间,生成AO活动对象
    2. 分析生成AO属性:查找形参变量声明放到AO对象,赋值为undefined
    3. 分析函数声明:查找函数声明放到AO对象并赋值为函数体。函数名为属性名,值为函数体;

    如果遇到AO对象上属性同名,则无情覆盖

  2. 逐行执行。

案例说明

拿的是上文中的代码示例。

  1. 第一步创建AO对象

    AO{ }

  2. 查找形参变量声明放到AO对象并赋值为undefined

    注意:fun函数里边的b是未经var声明的,所以是全局变量,不会被放在fun的AO上。

    AO{ a: undefined,//形参a与局部变量a同名 c: undefined }

  3. 实参赋值到形参

    AO{ a: 1, c: undefined, }

  4. 查找函数声明放到AO对象并赋值为函数体,fun函数没有函数声明,所以忽略这一步。

  5. 函数执行之前的预编译完成,开始执行语句

  6. 执行代码

    1. 首先执行打印变量b,而此时fun的AO里边并没有变量b,所以会去GO对象里边找,此时的GO对象b的值为10,所以第一行代码打印出10;

    2. 第二行代码首先要看的是b = 2,然后GO对象里边b的值就被改为2了。

      GO = { a : 1, b : 10, a2 : 20, function fun (a) { var a = b = 2; var c = 123; } }

    3. 然后b再赋值给a,变量a是属于局部变量a,所以fun的AO对象里边a的值被改为2。

      AO{ a: 2, c: undefined, }

    4. 接着下一个赋值语句是c = 123,所以AO对象中c的值被改为了123

      AO{ a: 2, c: 123, }

    5. 此时再执行console.log(a)的值就是AO对象里边a的值 2;执行console.log(b)的值就是GO对象b的值 2,至此函数fun执行完毕,紧跟着fun的AO也会被销毁

  7. 综上所述,依次打印出来的值为:1,undefined,10,2,2

总结预编译两个小规则:
  1. 函数声明整体提升(无论函数调用和声明的位置是前是后,系统总会把函数声明移到调用前面)
  2. 变量声明提升(无论变量调用和声明的位置是前是后,系统总会把声明移到调用前,注意仅仅只是声明,所以值是undefined
预编译前奏
  1. imply global(暗示全局变量-专业术语) 即:任何变量,如果未经声明就赋值,则此变量就位全局变量所有。(全局域就是window,这里再一次说明了JavaScript是基于对象的语言,base on window)
  2. 一切声明的全局变量,全是window的属性;var a=12;等同于window.a = 12;(会造成window这个对象特别臃肿)
  3. 函数预编译发生在函数执行前一刻(懒加载机制)

相关推荐:javascript学习教程、web前端开发视频教程