javascript预编译的过程
预编译的两种情况
全局:
1.全局 直接是script标签中的代码,不包括函数执行
执行前:
1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析
2.分析变量声明,变量名为属性名,值为undefined
3.分析函数声明,函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖
函数内部(局部):
1. 函数调用,也是会生成自己的作用域(AO:active object),AO活动对象. 函数调用时候,执行前的一瞬间产生的,如果有多个函数的调用,会产生多个AO
a. 函数执行前的一瞬间,生成AO活动对象
b. 分析参数,形参作为对象的属性名,实参作为对象的属性值
c. 分析变量声明,变量名为属性名,值为undefined,如果遇到AO对象上属性同名,不去做任何改变
d. 1.4 分析<b>函数声明</b>,函数名为属性名,值为函数体,如果遇到AO对象上属性同名,则无情覆盖
2. 逐行执行。
代码分析如下:
<script type="text/javascript"> console.log(a); console.log(b) var a = 100; console.log(a) var b = 200 var c = 300 function a(){ } function fun(){ } console.log(a);
</script>
全局 直接是script标签中的代码,不包括函数执行
执行前:
1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析
GO = {
自带的属性都不写
}
2.分析变量声明,变量名为属性名,值为undefined
GO = {
a : undefined,
b : undefined,
c : undefined
}
3.分析<b>函数声明</b>,函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖
GO = {
a : function a(){},
b : undefined,
c : undefined,
fun : function fun(){}
}
此时,GO就是预编译完成的最终对象,词法分析结束
4.逐行执行,分析过(变量声明,函数声明)不用管了,只管赋值(变量赋值)
11行的时候,a赋了一次值,值改变为100
GO = {
a : 100,
b : undefined,
c : undefined,
fun : function fun(){}
}
局部
<script type="text/javascript"> var num = 100; function fun(num){ console.log(num) } fun(5) fun(10) </script>
1.预编译的时候
GO = {
num : undefined,
fun : function
}
2.执行过程
走到9行
GO = {
num : 100,
fun : function
}
走到14行,函数的调用
3.函数调用,也是会生成自己的作用域(AO:active object),AO活动对象. 函数调用时候,执行前的一瞬间产生的,如果有多个函数的调用,会产生多个AO
3.1 函数执行前的一瞬间,生成AO活动对象
fun.AO = {
}
3.2 分析参数,形参作为对象的属性名,实参作为对象的属性值
fun.AO = {
num : 5
}
3.3 分析变量声明,变量名为属性名,值为undefined,如果遇到AO对象上属性同名,不去做任何改变
fun.AO = {
num : 5
}
3.4 分析函数声明,函数名为属性名,值为函数体,如果遇到AO对象上属性同名,则无情覆盖
4.逐行执行
综合分析:
<script type="text/javascript"> console.log(test); function test(test){ console.log(test); var test = 123; console.log(test); function test(){ } console.log(test); var test = function(){} console.log(test); } test(10); var test = 456 console.log(test); </script>
预编译开始,先生成一个GO{
}
1.看变量GO{
test:underfined
}
2.看函数声明GO{
test:function test(test){
console.log(test);
var test = 123;
console.log(test);
function test(){
}
console.log(test);
var test = function(){}
console.log(test);
}
}
把整个函数体给test
预编译完成,开始执行代码,第二行的结果是test函数的函数体
3到13行都是函数声明,不用管
第14行函数执行,传入参数10
函数执行的时候产生AO{
}
1.看参数AO{
test:10
}
2.看变量,变量同名,不用管变量AO{
test:10
}
3.看函数,函数和参数同名,函数把参数覆盖AO{
test:function test(){}
}
4.逐行执行
第三行打印名字为test的函数体,
第四行给test赋值123,第五行打印123
7到9行函数体声明不用管
第十行打印123
第十一行把一个匿名函数(没有函数名的函数)赋值给test
第十二行函数执行完毕
第十四行回到全局,把456赋值给test
第十五行打印456