今天學習了一下JS的預編譯,對此想做一篇博文用來總結一下今天學習的知識,以此來加深一下記憶。本博文進僅供參考。如有錯誤的地方還請各位博友指出錯誤。
希望我們共同學習。
首先先來一段代碼
JS是解釋一行執行一行,但是上面代碼卻打印出a的值為undefined?為什么?
到這里可能有很多人知道變量聲明聲明提升,函數聲明整體提升比如說這個。
這里打印的fn的值為 fn函數。但是其實者兩句話知識一個對預編譯出現的現象的一種總結。
很多問題不能夠使用這兩句話解決
console.log(a); var a = 123; function a(){}
這個結果是什么?現在這個初始a的結果應該是什么用上面的方法解決不了上面的問題;
說的怎么多那么什么是預編譯,到底什么是?
在函數(JS)執行的前一刻,會創建一個叫做執行期上下文的(AO)對象這個創建執行期上下文的過程叫做預編譯。
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對象
AO{
}
2.找到函數形參和變量聲明,將函數和形參名的作為Ao對象的屬性名,值為undefined
AO{
a : undefined,
b : undefined
}
代碼中只存在a形參和b變量
3.實參形參相統一
AO{ a : 1, b : undefined }
4.找到函數中的函數定義,函數名為AO對象屬性名,值為函數體
AO{ a : function a(){}, b : undefined, d : function d(){} }
因為AO對象中a屬性已存在修改值為函數,fn函數中還存在函數d聲明。這是執行器上下文對象為上面這樣
所以代碼的執行結果為:
function fn(a) { console.log(a);// AO對象的值為function a(){} var a = 123;// 變量聲明已經在預編譯的時候執行的了 在執行時不會執行變量聲明 改變Ao對象中屬性a值為123 console.log(a); // 123 function a(){}// 這也不執行 console.log(a); // 123 var b = function(){} // vaar b不執行 改變AO對象中的屬性b為function(){} console.log(b);// function() {} function d(){}// 不執行 } fn(1);
這樣最終結果就是了
但是我們一開始在全局中的那個問題還是沒有解決啊
其實在JS執行的前一刻也會創建對象只不過這個對象叫做GO對象全局執行器上下文,只不過他的預編譯不存在函數預編譯過程的第二步。全局不存在形參。他創建的對象叫做GO對象
console.log(a); var a = 123; function a(){}
1.創建GO對象
GO{
}
2.找到全局中的變量聲明,將函數和形參名的作為GO對象的屬性名,值為undefined
GO{
a :undefined
}
3.找到全局中函數聲明將函數作為GO對象的屬性名,值為函數
GO{
a :function a(){}
}
代碼執行結果為function a(){}