预编译铺垫
- imply global 暗示全局变量
即任何变量,如果变量未经声明就赋值,此变量就为全局对象window所有
如 a = 123; 那么就相当于 window.a = 10;
再如 function test(){
var a = b = 10;
}
//因为赋值操作是自左到右的 那么此时b是未声明的变量 那么b就归window所有 可以用window.b访问
//然后声明a变量 再把b的值赋给啊 但是声明的a变量在函数中 属于局部变量 不属于window 不可以用window.a访问
2. 一切声明的全局变量,都是window的属性(相当于在window中定义了属性)
如 var a = 123; 表明window.a = 123;
相当于 window{
var a : 123
}
3. window就是全局的域,对于一切定义在全局的变量,都归window所有
那么下次再访问这个全局变量时,会直接去window里面找有没有这个变量预编译
预编译发生在函数执行的前一刻
预编译四部曲
1.创建AO对象 Activation Object(活跃对象/执行期上下文)
2.找形参和变量声明(不管是否在if这些判断语句中),将变量和形参名作为AO属性名,值为undefined
3.将实参值和形参统一
4.在函数体里面找函数声明,然后赋值为函数体 
例一
        function test(a){
            console.log(a);
            var a = 2;
            console.log(a);
            function a(){}
            console.log(a);
            var b = function(){}
            console.log(b);
            function d(){}
        }
        test(1);
1  创建AO对象
AO{
//此时AO对象为空
}
2  找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
AO{
a : undefined,  //这个a是函数的参数
b : undefined,  //函数里面声明的变量
}
3  将实参值和形参统一
AO{
a : 1,  //实参传值
b : undefined,
}
4  在函数体里面找函数声明,值赋予函数体(注意这里var b = function(){}是函数表达式  不是函数声明)
AO{
a : function a(){},  //变量名一样  值会被覆盖
b : undefined,
d : function d(){}
}
此时函数预编译已经完成的,预编译后执行代码:
是从AO对象中拿变量
第一条执行的是控制台打印出a的值,所以输出AO中的function a () {};
第二条语句赋值给a,则AO对象中a的值被覆盖为2;
即  AO{
a : 2,
b : undefined,
d : function d(){}
}
第三条语句控制台打印AO中a的值为2;
第四条为声明,预编译处理过所以直接跳过;
第五条打印出a的值,AO中a的值一样为2;
第六条为赋值,b的值为function () {};
即  AO{
a : 2,
b : function (){},
d : function d(){}
}
第七条打印出AO中b的值function () {};
第八条声明,预编译处理过所以直接跳过;
所以输出结果应该是
function a () {};
2;
2;
function () {};
例二:
        function test(a,b){
            console.log(a);
            c = 0;
            var c;
            a = 3;
            b = 2;
            console.log(b);
            function b(){}
            function d(){}
            console.log(b);
        }
        test(1);
1
AO{
//空
}
2
AO{
a : undefined,
b : undefined,
c : undefined
}
3
AO{
a : 1,
b : undefined
c : undefined
}
4
AO{
a : 1,
b : function b(){},
c : undefined,
d : function d(){}
}
所以输出结果应该是
1;
2;
2;
由上述例子类推到对于全局的预编译
因为全局不用形参  所以第二步少了形参
而且全局没有实参的说法  所以没有第三步
GO的对象先与AO对象创建
即:
1  创建GO对象  Global Object  GO===window  GO即为window
2  找变量声明,将变量作为GO属性名,值为undefined
3  在全局里面找函数声明,然后赋值为函数体
例一
console.log(a);
var a  = 1;
对应的GO为
GO{
a : undefined
}
//所以输出结果为undefined
例二
console.log(a);
var a  = 1;
function a(){}
GO{
a : function a(){}
}
//所以输出结果为function a(){}
例三
输出:
undefined;
200;
例四
输出结果为:
2;
undefined;
undefined;
10;
100;
123;
