要知道预编译要先知道编译过程
编译过程
- 1 通篇语法分析,找出低级错误。
- 2 预编译。
- 3 解释性执行。
首先解释第三步:js作为解释性语言,在执行代码的时候是编译一行,处理一行的,所以哪怕报错的前一行代码,依旧会执行。
现在说预编译
首先介绍两个概念:imply global , window.
imply global,暗示全局变量:任何未经声明的变量如果未经声明就使用(赋值)就会为全局对象所有;举个栗子:a = 10——–>window.a = 10; 当然a如果在全局声明,效果一样。
window:一切全局变量都是window的属性
var a = 123; - - - >(相当于)
window{
a = 123;
}
后面的访问过程其实也是从window的属性中获取。
预编译过程
现在可以解释预编译的过程了
总的来讲四句话:
* 1 创建AO对象(Activation Object,执行期上下文)
* 2 找形参和变量声明,将变量和形参名作为AO属性名,值初始化为undefined;
* 3 用实参值代替掉3中的形参值;
* 4 在函数里找函数声明,值给函数名。
以上就是在函数体内部执行预编译的过程啦
在全局的话只需要加上GO(Golobal Objective),把全局变量写进去,再让AO优先级远高于GO即可
function test(){
console.log(b);
if(a){
var b = 100;
}
c = 234;
console.log(c);
}
var a;
test();
a = 10;
console.log(c);
来一个题
AO{
b = undefined;
}
Go{
c = 234;
a = undefined;
}
结果显然,为
undefined
234
234
再来一个吧
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);
这道难度明显大了些,有很多重复的使用。
方法相同。
1.AO{//第一步,找出函数体内声明
a:undefined;
b:undefined;
}
2.AO{
a:1;//把实参值传进来
b:undefined;
}
3.AO{
a:function a(){};参考第四步
b:undefined;
}
至此,预编译执行完毕
执行部分:一进函数体,输出a,就是function a (){}
再下来给a赋值123,打印就是123,而接下来的一行被预编译3提前了,所以略过。再次打印,还是123.b的值本身是undefined,赋值变成了函数function(){};
所以 答案
function a(){}
123
123
function (){};
感谢访问,