目录
阶段(三个)
预编译过程
1. JavaScript代码执行之前的预编译
案例说明
2. 函数执行前的预编译
总结
预编译两个小规则:
预编译前奏
首页 web前端 js教程 完全掌握JavaScript预编译过程

完全掌握JavaScript预编译过程

Feb 10, 2022 pm 05:57 PM
html javascript 前端

本篇文章给大家带来了关于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前端开发视频教程

以上是完全掌握JavaScript预编译过程的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1653
14
CakePHP 教程
1413
52
Laravel 教程
1305
25
PHP教程
1251
29
C# 教程
1224
24
HTML 中的表格边框 HTML 中的表格边框 Sep 04, 2024 pm 04:49 PM

HTML 表格边框指南。在这里,我们以 HTML 中的表格边框为例,讨论定义表格边框的多种方法。

HTML 中的嵌套表 HTML 中的嵌套表 Sep 04, 2024 pm 04:49 PM

这是 HTML 中嵌套表的指南。这里我们讨论如何在表中创建表以及相应的示例。

HTML 左边距 HTML 左边距 Sep 04, 2024 pm 04:48 PM

HTML 左边距指南。在这里,我们讨论 HTML margin-left 的简要概述及其示例及其代码实现。

HTML 表格布局 HTML 表格布局 Sep 04, 2024 pm 04:54 PM

HTML 表格布局指南。在这里,我们详细讨论 HTML 表格布局的值以及示例和输出。

HTML 输入占位符 HTML 输入占位符 Sep 04, 2024 pm 04:54 PM

HTML 输入占位符指南。在这里,我们讨论 HTML 输入占位符的示例以及代码和输出。

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在这里我们还分别讨论了 HTML 有序列表和类型的介绍以及它们的示例

HTML onclick 按钮 HTML onclick 按钮 Sep 04, 2024 pm 04:49 PM

HTML onclick 按钮指南。这里我们分别讨论它们的介绍、工作原理、示例以及各个事件中的onclick事件。

在 HTML 中移动文本 在 HTML 中移动文本 Sep 04, 2024 pm 04:45 PM

HTML 中的文本移动指南。在这里我们讨论一下marquee标签如何使用语法和实现示例。

See all articles