1. 程式人生 > >淺談JavaScript預編譯原理

淺談JavaScript預編譯原理

全局變量 obj 預處理 http 對象 自然 net jet object

這兩天又把js的基礎重新復習了一下,很多不懂得還是得回歸基礎,大家都知道js是解釋性語言,就是編譯一行執行一行,但是在執行的之前,系統會做一些工作:

1,語法分析;

2,預編譯;

3,解釋執行。

語法分析很簡單,就是引擎會簡單的檢查一下你的代碼有沒有什麽低級的錯誤,解釋執行就是執行代碼,執行代碼之前會進行預編譯,預編譯簡單理解就是在內存中開辟一些空間,存放一些變量與函數。下面我詳細說一下:

預編譯可以簡單的分成全局預編譯和函數體預編譯,函數體預編譯可以從四個規則入手;

1,創建AO對象;AO{ }

2,找形參和變量聲明,將變量和形參名作為AO的屬性名,並賦值為undefined

3,將實參和形參統一;

4,在函數裏找函數聲明 ,賦值函數體。

記住以上四條規則,下面通過一個簡單的案列說明一下:

function test(){
console.log(a);
console.log(b);
var b = 234;//變量聲明
console.log(b);
a = 123;//變量聲明
console.log(a);
function a(){}//函數聲明
var a;
b = 257;
var b = function (){}//變量聲明
console.log(a);
console.log(b);
function c(y){//函數聲明
var y = 1;
};
}
test(1)
讓我們看看引擎對這段代碼做了什麽吧
1,創建AO對象;Activation Object AO{ }
2,找形參和變量聲明,將變量和形參名作為AO的屬性名,並賦值為undefined
AO{
b:undefined;
a:undefined;

}
3,將實參和形參統一;
4,在函數裏找函數聲明 ,賦值函數體。所以此時的a會被函數體替代
AO{
a:function a(){}
b:undefined
c:function c(y){
var y = 1;
}
}
當頁面預處理完之後便會開始執行,根據編譯一句執行一句的原則,此時console.log(a)的值自然為:function a(){},console.log(b)的值為:undefined.
隨後b被賦值為234,所以第二個console.log(b)的值為:234,以此類推,第二個console.log(a)的值為:123,
b經歷了第三次賦值257後,又被function(){}賦值,所以最後console.log(b)的值為:function(){},console.log(a)的值為:123,

全局預編譯比函數體預編譯少了第三條:

1,創建GO對象;即global objetct GO{ }

2,找形參和變量聲明,將變量和形參名作為AO的屬性名,並賦值為undefined

4,在函數裏找函數聲明 ,賦值函數體。

下面也通過一個簡單的列子解釋一下:

function test(){
console.log(b);//undefined
if(a){
var b = 100;
}
console.log(b)//undefined
c = 456;
console.log(c);//456
}
var a
console.log(a)////undefined
test()
a = 10;
console.log(a)//10
console.log(c)//456

首先定義創建GO對象,隨後將變量和形參作為屬性名,並賦值為undefined,如下:
GO{
a:undefined;
c:undefined;
}
然後在函數生命裏賦值函數體,但此時沒有函數體,所以不用賦值,
下面就是開始執行語句,所以一第個console.log(a)為undefined;第二個為10,c為456(註意此時c沒有命名,直接提升為全局變量)
當執行到test()的時候會主動預編譯function test()裏面的內容,此時會創建AO對象.

還有一篇關於預編譯的文章寫的也比較清楚:http://blog.csdn.net/q1056843325/article/details/52951114

淺談JavaScript預編譯原理