js关于函数预编译的研究
前言:js执行过程为分为3步
- 语法分析:通篇扫描有无语法错误 如中文符号或者缺少大括号
- 预编译:函数声明整体提升,变量 声明提升
- 解释执行
总结:函数预编译为4部曲,预编译发生在函数执行的前一刻
1.创建 AO 对象
2.找形参和变量声明,将形参和变量作为AO属性名,值为undefined
3.将实参值和形参统一
4.在函数体里面找函数声明,值赋予函数体
举例解释说明,更好理解
function fn(a){
console.log(a);
var a=123;
console.log(a);
function a(){}
console.log(a);
var b = function (){}
console.log(b);
function d(){}
}
fn(1)
预编译过程:
第一步 生成一个AO对象, AO{ }
第二步 :
1.先找到 形参a ,添加新属性a ,赋值undefined,此时 AO -> AO { a:undefined }
2.接下来 var a , AO对象已有a属性, 不用操作
3.发现 var b , 添加新属性b , 赋值undefined,此时 AO -> AO { a:undefined , b:undefined }
第三步:
将实参1与形参统一 ,此时 AO -> AO { a:1 ,b:undefined }
第四步:
1.发现函数声明 function a(){} ,AO对象已有a属性,更改值为函数体,此时 AO -> AO { a:function a(){} , b:undefined }
2.发现函数声明 function d(){} ,此时 AO -> AO { a:function a(){} , b:undefined ,d:function d(){} , }
执行函数体过程:
1. console.log(a) ,去AO对象寻找a, 打印结果为 function a(){}
2. var a=123, var a已经预编译 ,只执行 a=123, 此时AO-> AO { a:123 , b:undefined ,d:function d(){} , }
3.console.log(a) ,去AO对象寻找a ,打印结果为 123
4.function a(){} 已经预编译 ,跳过
5.console.log(a) ,去AO对象寻找a ,打印结果不变仍为 123
6. var b = function () {} ,var b已经预编译 ,只执行 b=function () {}, 此时AO-> AO { a:123 , b:function () {} ,d:function d(){} , }
7.console.log(b) ,去AO对象寻找b ,打印结果为 function (){}
8. function d() {} 已经预编译 ,跳过
打印结果为:
如有错误,欢迎各位大佬指正