预编译
1.预编译
1.预编译执行的时间:在解释函数执行之前。
(js运行三部曲 1.语法分析;2.预编译; 3.解释执行)
2.由于【预编译】才会导致函数声明提升,解决函数执行顺序的问题。
3.全局变量
1) 未经声明的变量全归window所有;
2) 全局上的变量,即使声明了也归window所有;
3) window就是全局的域。
2.预编译的步骤
1.创建局部变量AO对象;
2.找到形参和变量声明,将变量和形参名作为AO属性名,值为undefined;
3.将实参值和形参统一;(如果没有形参这个步骤就跳过)
4.在函数里面找函数声明(不是函数表达式),值赋予函数体。
例子
在函数执行之前变量先进行预编译产生AO{},预编译得到变量的值,在函数执行时发生变化。
function test(a,b){
console.log(a);//1
c=0;
var c;
a=3;//a:1=>3
b=2;//b:function b(){}=>2
console.log(b);//2
function b(){}
function d(){}
console.log(b);//2
console.log(a);//3
}
//AO{
// a:undefied=>1,
// b:undefied=>2=>function b(){},
// c:undefied=>0,
// d:function d(){}
//}
test(1, 2)//1 2 2 3
2.预编译再全局中
预编译发生在全局(少了第三步)
1.生产了一个 GO 对象 Global Object,GO === Window
a.任何全局变量都是Window上的属性
b.如果一个变量没有经过声明就赋值了,是归属于window的。
2.找到变量声明,将变量和形参名作为GO属性名,值为undefined;
3.在函数里面找函数声明(不是函数表达式),值赋予函数体。
例子1(先运行GO再运行AO)
//GO{
// test:function test(){}
//}
function test(){
var a=b=123;
//b 没有有声明添加到GO{}里面,GO.b:123
//AO.a:undefined => 123
console.log(window.a);//undefined
console.log(window.b);//123
console.log(a);//123;
console.log(b);//123 (AO没有就到GO里面找)
}
//AO{
// a:undefined
//}
test();
//undefined 123 123 123
例子2
//GO{
// test:undefined => function test(){}
//}
function test(test){
console.log(test);//funtion test(){};
var test=234;//AO:funtion (){} => 234
console.log(test);//234
function test(){}
}
//AO{
// test:undefined => 1 => function test(){}
//}
test(1);//function test(){} 234
var test=123;
例子3
//GO{
// a:100;
// demo:function (){};
//}
a=100;
function demo(e){
function e(){}
arguments[0]=2;//AO.e:function e(){}=>2,与形参做映射
document.write(e);//2
if(a){//AO.a:undefined 不进入里面
var b=123;
}
var c;
a=10;//AO.a:undefined => 10
var a;
document.write(b);//undefined
function c(){}
f=123;//f 没有有声明添加到GO{}里面,GO.f:123
document.write(c);//function c(){}
document.write(a);//10
}
var a;
//AO{
// e:undefined;=>1=>function e(){};
// b:undefined;
// c:undefined;=>function (){}
// a:undefined;
//
//}
demo(1);
document.write(a);//100
document.write(f);//123