关于预编译的过程与理解
预编译大致分为四部分:
1.创建AO对象
2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
3.将实参值和形参统一
4.在函数体里面找到函数声明,值赋予函数体
实例
<script>
function fn(a){
console.log(a); //function a(){}
var a = 123;
console.log(a); //123
function a(){}
console.log(a); //123
var b = function(){}
console.log(b) //function (){}
function d(){}
}
fn(1)
</script>
预编译是发生在函数执行前。
1.创建AO对象 (Activation Object)(执行期上下文)
2.
AO={
a:undefined,
b:undefined,
}
3.找到实参值赋予到形参里去。
AO={
a:1,
b:undefined,
}
4.在函数体里面找到函数声明,值赋予函数体
AO={
a:function a(){},
b:undefined,
d:function d(){}
}
------------预编译过程结束;函数开始执行
<script>
function fn(a){
console.log(a); //function a(){}
//第一个console就是读取AO里面的属性值;
var a = 123;
//var变量提升但是赋值没有提升。AO里面的属性 a = 123.
console.log(a); //123
function a(){}
console.log(a); //123
var b = function(){}
//var变量提升但是赋值没有提升。AO里面的属性 b = function(){}
console.log(b) //function (){}
function d(){}
}
fn(1)
</script>
在有些人口中,遵循两句话就能理解预解析。
1.函数整体提升。2.变量声明预解析不会提升赋值。
但在下面这个例子是行不通的
<script>
console.log(a); //得到的是function a(a){}的函数
function a(a){
var a = 234;
var a = function(){}
}
a();
var a = 123;
</script>
如果要想记住上面的的话,可能还需要记住一句话:
同一个标识符的情况下,变量声明与函数声明都会提升;函数声明会覆盖变量声明,但不会覆盖变量赋值,即:如果声明变量的同时初始化或赋值那么变量优先级高于函数。