预编译时会默认有两种现象
1、函数声明整体提升
无论还是写在什么位置,通过预编译,都会将函数放在所有逻辑的最前面
<script type="text/javascript">
test();//这里也可以执行test函数,因为默认是将下面function test(){}放在了最前方
function test(){}
</script>
2、变量 声明提升
<script type="text/javascript">
console.log(a);//这里也可以a,且输出内容为undefined,因为默认是将下面的var a放在了最前方
var a = 123;//其实这里相当于声明变量并赋值,即var a ; a = 123;
</script>
预编译前奏
一、imply global(暗示全局变量):即任何变量,如何变量未经声明就赋值,此变量就为全局对象所有。
- eg: a=123; //a为全局window所有
- eg: var a = b= 123; // 依照从右向左赋值的过程,b=123,即b为全局window所有,但是a并不是的
- function test() { var a = b =123;} str(); console.log(a);-->a is not defined; console.log(b)-->123
二、一切声明的全局变量,全是window的属性
- eg: var a =123; ===>window.a = 123;
window是全局的域;一切定义在全局的变量都归window所有
var a = 123;
console.log(a);====>console.log(window.a);
函数预编译
一、四部曲
- 创建AO对象(Activation Object 执行期上下文)
- 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
- 将实参值和形参统一
- 在函数体里面找函数声明,值赋予函数体
- 练习:
- 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);
- 预编译时创建AO对象值变化过程
1. AO{ }
2. AO{ a : undefined, b : undefined}
3. AO{ a : 1, b : undefined}
4. AO{ a : 1, b : undefined, d : }
5. AO{ a : function a(){}, b : undefined, d : function d(){} }
7) AO对象的作用就是作用域,然后回头再去查看代码的执行
- function fn(a){
- console.log(a); //因为AO{ a : function a(){}, b : undefined, d :function d(){} },所以输出内容为function a(){}
- var a = 123; // 由于变量声明提升,那么a已经在函数体最初的时候被声明过了,且得到的AO对象如上。那么剩余的就是a被重新赋值还未执行,所以AO{ a : 123, b : undefined, d :function d(){} }
- console.log(a); / /所以输出内容为123
- function a(){}; // 函数声明整体提升了,这里不再执行了
- console.log(a); //因为AO{ a : 123, b : undefined, d :function d(){} },所以输出内容为123
- var b = function (){};// b被重新赋值,所以AO{ a : 123, b : function b(){}, d :function d(){} }
- console.log(b); // ,所以输出内容为function b(){}
- function d(){};
- }