预编译的两种情况
全局:
1.全局 直接是script标签中的代码,不包括函数执行
执行前:
1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析
2.分析变量声明,变量名为属性名,值为undefined
3.分析函数声明,函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖
函数内部(局部):
- 函数调用,也是会生成自己的作用域(AO:active object),AO活动对象. 函数调用时候,执行前的一瞬间产生的,如果有多个函数的调用,会产生多个AO
1.1. 函数执行前的一瞬间,生成AO活动对象
1.2 分析参数,形参作为对象的属性名,实参作为对象的属性值
1.3. 分析变量声明,变量名为属性名,值为undefined,如果遇到AO对象上属性同名,不去做任何改变,
注意!!!
如果变量名与形参名相同,变量不会覆盖形参,是以形参为准。
例1
console.log(test); ----> **输出函数体**
function test(test){
console.log('test='+test); ----> **输出undefined**
var test = 123;
}
test();
例2
console.log(test); ----> 输出函数体
function test(test){
console.log('test='+test); ----> *输出10*
var test = 123;
}
test(10);
1.4 分析函数声明,函数名为属性名,值为函数体,如果遇到AO对象上属性同名,则无情覆盖
- 逐行执行
总之:不管全局还是局部,都是先预解析声明变量,其次是声明函数。
需注意的就是:
当解析函数声明时与变量同名则无情覆盖。
函数内的形参与变量同名,以形参为准;
赋值函数(即变量=一个匿名函数)是属于变量声明;
综合练习例子
<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>