预编译

js 预编译是什么

先看一段代码

// 函数
function fn(a, c) {
  console.log(a, "a1");
  var a = 123;
  console.log(a, "a2");
  console.log(c, "c1");
  // 函数声明
  function a() {}
  console.log(a, "a3");
  console.log(b, "b1");
  // 函数表达式
  var b = function () {};
  console.log(b, "b2");
  // 函数声明
  console.log(d, "d");
  function d() {}
  function c() {}
  console.log(c, "c2");
}
//调用函数
fn(1, 2);

你知道上面代码的执行结果,如果你不复制代码到浏览器中看结果,那么我相信你已经理解了预编译,也就不用再看下去了,如果你不知道结果,那么你可以尝试看下去。相信你会有所收获。

什么是预编译

预编译分为全局预编译和局部预编译,上面的代码就是局部预编译,全局预编译发生在页面加载完成时候执行,而局部预编译发生在函数执行前。

全局预编译步骤

  • 创建 GO 对象(全局对象)
  • 找变量声明,将变量名作为 GO 属性名,值为 undefined
  • 查找函数声明,作为 GO 属性,值赋值给函数体

局部预编译步骤

  • 创建 AO 对象(执行上下文)
  • 找形参和变量声明,将变量和形参作为 AO 属性名,值为 undefined
  • 将实参值和形参值统一
  • 在函数体里面找函数声明,值赋值给函数体

逐步分析代码

// 开始会创建 AO 局部编译对象
AO:{

}
// 然后查找形参和变量声明作为 AO的属性并且赋值为undefined
// 因为 function d(){} 是函数体 要到最后一步才查找
AO:{
    a:undefined,
    c:undefined,
    b:undefined,
}
// 将形参和实参的值统一 赋值给AO对应的属性
AO:{
   a:1,
   c:2,
   b:undefined
}
// 在函数体里找函数声明,值赋值给函数体(如果函数声明和变量一样,那么会覆盖变量声明)
// 因为 b 是函数表达式,不是函数声明,所以此时b还是undefined
AO:{
  a:function a(){},
  c:function c(){},
  b:undefined,
  d:function d(){}
}
// 执行到这里接下来就要开始 js解释执行,也就是逐行执行代码
// 函数
function fn(a, c) {
  console.log(a, "a1");
  var a = 123;
  console.log(a, "a2");
  console.log(c, "c1");
  // 函数声明
  function a() {}
  console.log(a, "a3");
  console.log(b, "b1");
  // 函数表达式
  var b = function () {};
  console.log(b, "b2");
  // 函数声明
  console.log(d, "d");
  function d() {}
  function c() {}
  console.log(c, "c2");
}
//调用函数
fn(1, 2);
// 预编译结果
AO:{
  a:function a(){},
  c:function c(){},
  b:undefined,
  d:function d(){}
}
// 首先执行console.log(a,'a1')
function a(){} "a1"
// 接下来 a赋值变成123 AO 的属性 a就变成了123
// 打印a2
123 "a2"
// 打印c1
function c(){} "c1"
// 打印a3 此时AO属性的 a值依然是123
123 "a3"
// 打印 b1 此时b是undefined

undefined "b1"
// 这个时候函数 function (){} 赋值给b 所以AO属性的b 为 function(){}
// 打印 b2
function(){} 'b2'
// 打印 d
function d(){} "d"
// 打印c2
function c(){}  "c2"

最终答案

1615363787(1).jpg

全局预编译

全局预编译根据相对应的步骤逐步分析即可

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 文章目录 JavaScript运行三部曲 JavaScript预编译 01 关于预编译的一些知识点 02 预编译四...
    寒羽鹿阅读 3,502评论 1 0
  • 预编译是js的一个特色,也算是闭包之前最难的一个知识点。 预编译有4句公式,而这4句公式只要背熟就能理解预编译。 ...
    德育处主任阅读 5,324评论 0 7
  • JS 运行三部曲 JS 运行三部曲语法分析预编译解析执行 预编译前奏暗示全局变量 imply global全局变量...
    席坤阅读 2,865评论 0 0
  • JS运行三部曲 js运行代码共分三步 语法分析 预编译 解释执行 JavaScript代码在运行时,首先会进行语法...
    HTAO濤阅读 1,639评论 0 1
  • 小练习1:N的阶乘 递归需要注意的两点:1.找规律、2.找出口。没有出口的话递归就会无限死循环,所以必须用一个已知...
    耦耦阅读 1,504评论 0 0

友情链接更多精彩内容