變量提升聲明,不提升賦值
console.log(a);// undefined
var a=1;
輸出結果undefined,是因爲把變量聲明提升到了頂部,等價於如下代碼:
var a;
console.log(a);// undefined
a=1;
函數整體提升
fun();// 1
function fun(){
console.log(1);
};
輸出結果是1,因爲把整個函數都提升到了頂部,等價於如下代碼:
function fun(){
console.log(1);
};
fun();// 1
深入理解真正的預編譯
預編譯的過程:
1、創建VO(變量對象 Variable Object)或AO(活動對象 Activation Object)。
2、找形參和變量聲明,將變量和形參名作爲AO屬性名,值爲undefined。
3、將實參值和形參統一,實參的值賦給形參。
4、在函數體裏面找函數聲明,值賦予函數體。
fun(a,b,3);
function fun(a,b,c){
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(e);
function d(){};
var e=function(){};
console.log("—————我是分割線—————");
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(e);
}
function b(){};
var a=1;
輸出結果:
接下來進行分析,建議扣出上面的代碼,對照着看,那我們開始飆車了—>
1、首先系統自動創建變量對象VO={};:
VO={}
2、然後函數和變量提升聲明:
VO={
a:undefined
b:undefined
fun:undefined
}
3、然後函數賦值提升:
VO={
a:undefined
b:function b(){}
fun:function fun(){}
}
4、然後執行fun(a,b,3);,將AO中的a、b以及常量3傳遞給fun(),等價於如下代碼:
fun(undefined,function b(){},3)
function fun(a,b,c){...}
5、我們繼續分析,在fun()中,又會創建一個活動對象AO={};並且提升函數和變量的聲明:
AO={
a:undefined
b:undefined
c:undefined
d:undefined
e:undefined
}
6、在函數體中,會將實參值和形參統一,也就是將實參的值賦給形參:
AO={
a:undefined
b:function b(){}
c:3
d:undefined
e:undefined
}
7、然後函數賦值提升,在函數體裏面找函數聲明,值賦予函數體:
AO={
a:undefined
b:function b(){}
c:3
d:function d(){}
e:undefined
}
注意:d與e的區別!
8、接下來執行完第一波console.log();後,再將AO中e的值改變爲匿名函數:
AO={
a:undefined
b:function b(){}
c:3
d:function d(){}
e:function (){}
}
9、再執行第二波console.log();就完事了
——————————2019年7月4日——————————
今天突發奇想,要是在fun()中重新聲明函數b,結果會是怎樣?
fun(a,b,3);
function fun(a,b,c){
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(e);
function b(){console.log('new')}
function d(){};
var e=function(){};
console.log("—————我是分割線—————");
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(e);
}
function b(){console.log('old')};
var a=1;
這裏就得補上一個知識點,函數聲明提升>形參提升>變量提升
所以新聲明的b(){console.log('new')}
會替換掉AO中原本的形參b(){console.log('old')}
這裏再寫一個經典:
var name = 'xiaoxiao';
function fun() {
alert(name);
var name = 'dada';
alert(name);
alert(age);
}
fun();
猜猜答案是什麼?