js的预编译

// 什么是预编译: 引擎会在解释javaScript代码之前对其进行编译,编译阶段中的一部分工作就是找到所有的声明,并用适合的作用域将它们关联起来

// 预编译什么时候发生:预编译分为全局预编译和局部预编译,全局预编译发生在页面加载完成时执行,而局部预编译发生在函数执行的前一刻

// 全局编译的步骤

// 1、生成GO(global object)对象, 这个GO就是window

// 2、将全局的变量声明(的名)储存GO对象中,value为undefined

// 3、将全局的函数声明的函数名作为GO对象中的key,函数整体内容为value储存到GO对象中

// 例子:

// var a;

// function fun() {}

// function abc() {}

// function a() {}

// console.log(a);

// var a = 100;

// console.log(a);

// 会生成一个对象(GO)

// 分析变量声明(var)——变量作为GO对象的属性名,值为undefined(变量的赋值是js代码执行的时候发生的,不是预编译的时候)

// 分析函数声明(function)——函数名作为GO对象的属性名,值为函数体(如果遇到同名,直接覆盖

// GO{

// a: undefined; function a(){},

// fun: function fun(){},

// abc:function abc(){},

// }

// 所以当代码执行到console.log(a)的时候,打印的是function a() {}

// 当执行到var a = 100的时候,GO对象就变成下面的样子

// GO{

// a: undefined; function a(){}; 100,

// fun: function fun(){},

// abc:function abc(){},

// }

// 所以当代码执行到第二个console.log(a)的时候,打印的是100

// ----------------------------------------------------------

// 局部编译的步骤

// 1、执行前的一瞬间,会生成一个AO(action object)对象

// 2、找形参和边的声明,作为AO对象的属性名,值为undefined

// 3、实参和形参相统一

// 4、找函数声明,如果跟变量的名称一样,则会覆盖前面的声明

// 例子

function fn(a) {

console.log(a); // function a() {}

var a = 123;

console.log(a); // 123

function a() {}

console.log(a); // 123

var b = function() {} // 函数表达式

console.log(b); // function() {}

function d() {}

var d = a

console.log(d); // 123

}

fn(1)

// 预编译执行的过程

// 第一步 创建AO对象

// AO {

// }

// 第二步 到函数体作用域里找形参和变量声明,将形参和变量作为AO对象的属性名,值为undefined

// AO{

// a: undefined,

// b:undefined,

// d:undefined

// }

// 第三步 将实参和形参统一

// AO{

// a: undefined; 1,

// b:undefined,

// d:undefined

// }

// 第四步 在函数体里找函数声明,将函数名作为AO对象的属性名,值赋予函数体,重复则覆盖之前的

// AO{

// a: undefined; 1; function a() {},

// b:undefined,

// d:undefined; function d() {}

// }


 

// 代码执行过程

// 当执行到第一个console.log(a);的时候AO对象如下,所以打印出function a() {}

// AO{

// a: undefined; 1; function a() {},

// b:undefined,

// d:undefined; function d() {}

// }

// 当执行到第二个console.log(a);的时候AO对象如下,所以打印出123

// AO{

// a: undefined; 1; function a() {}; 123,

// b:undefined,

// d:undefined; function d() {}

// }

// 当执行到第三个console.log(a);的时候AO对象如下,所以打印出123

// AO{

// a: undefined; 1; function a() {}; 123,

// b:undefined,

// d:undefined; function d() {}

// }

// 当执行到console.log(b);的时候AO对象如下,所以打印出匿名函数function(){}

// AO{

// a: undefined; 1; function a() {}; 123,

// b:undefined; function(){},

// d:undefined; function d() {}

// }

// 当执行到console.log(d);的时候AO对象如下,所以打印出123

// AO{

// a: undefined; 1; function a() {}; 123,

// b:undefined; function(){},

// d:undefined; function d() {}; 123

// }

// 函数执行完毕,销毁AO对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值