分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

JS运行三部曲(预编译)

发布时间:2023-09-06 02:35责任编辑:郭大石关键词:编译

JS运行的三个步骤:

  1. 语法分析
  2. 预编译
  3. 解释执行

语法分析:通俗来说就是通篇检查你的代码有没有语法错误,有语法错误的话,程序是不会执行的

解释执行:也就是程序读一句执行一句

最重点的也就是预编译了,那么预编译到底是什么?它发什么在什么时候?

先来段代码压压惊

function fn (a) { ???console.log(a) ???var a = 123; ???console.log(a) ???function a () {} ???console.log(a) ???console.log(b); ???var b = function () {} ???console.log(b); ???function d () {} ???console.log(d)}fn(1)

这是打印结果

ƒ a() {}123123undefinedƒ () {}ƒ d() {}

是不是有些地方有点懵逼和意外,其实这就是预编译捣的鬼,预编译就是在函数执行之前,在你的内存中申请一点空间,存放变量和函数
下面说说预编译到底是怎样的过程,也就是上面函数到底发生了什么

预编译过程:

  1. 创建AO对象(Active Object)
  2. 找形参和变量声明,将形参和变量声明作为AO对象的属性名,值为undefined
  3. 将实参与形参统一(把实参值赋予形参)
  4. 在函数体里找函数声明,把函数声明也作为AO对象的属性名,值为函数体()

上面那段代码,fn函数执行之前,先发生预编译过程

第一步

AO = { }

第二步

AO = { ?????a:undefined, ?????b:undefined}

第三步

AO = { ?????a:1, ?????b:undefined}

第四步

AO = { ?????a:function (){}, ?????b:undefined, ?????d:function (){}}

第四步代表预编译完成,然后函数执行

AO = { ?????a:123, ?????b:function (){}, ?????d:function (){}}
function fn (a) { ???console.log(a) ???????????//这时函数未执行,打印function a(){} ???var a = 123; ???????????//此时执行了a=123 ???console.log(a) ???????????//打印123 ???function a() {} ???console.log(a) ???????????//打印123 ???console.log(b); ???????????//此时函数未执行,打印undefined ???var b = function () {} ????console.log(b); ???????????//此时执行了 b=function(){},打印function(){} ???function d () {} ???console.log(d) ???????????//打印function d(){}}} ???????????fn(1)

举几个‘栗子’

//1. function fn(a,b) {console.log(a); ??//打印1 ???c = 0; ???var c;console.log(b); ??//打印function b() {} ???a = 3; ???b = 2; ???console.log(b); ???//打印2 ???function b() {}; ???function d() {}; ???console.log(b) ????//打印2}fn(1);
//2.console.log(bar()); ?????//打印function foo() { //body }function bar(a,b) { ???return foo; ???foo = 10; ???function foo(){ ?????????//body ???} ???var foo = 11;}
//3.console.log(bar()); ?????//打印11function bar(a,b) { ???foo = 10; ???function foo(){ ???????//body ???} ???var foo = 11; ???return foo; ??}

以上是单个函数发生的预编译和函数执行过程,那么在<script></script>整个脚本中,是怎么样的呢?

<script type="text/javascript">  var a = 1;  function b () {  var x = 3;  function d () {}  }  var c = function () {    var y = 4;  }</script>

同样的过程,在语法分析之后,开始预编译,不过此时预编译创建的叫GO对象,(Global Object)

GO/window = {a:undefined,c:undefined,b:function b () { ?????var x = 3; ?????function d () {} ?????????}}

函数执行:

GO/window = {a: 1,c: function () { ?var y = 4; ?},b: function b () {var x = 3;function d () {} ???????????}}

在执行b函数之前,将b函数预编译,也就是创建b函数的AO对象
如果有两个<script></script>呢?那就先执行完一个,再执行下一个。

注意问题:
预编译只有变量声明、函数声明,并不会发生赋值,赋值发生在执行阶段
匿名函数function (){ } 不参与预编译

JS运行三部曲(预编译)

原文地址:https://www.cnblogs.com/jiahuasir/p/10571349.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved