JavaScript預編譯詳解


一、js運行三部曲:

1.語法分析(通篇掃描看有沒有語法錯誤)

2.預編譯

3.解釋執行

 

二、預編譯前奏

  1、imply global 暗示全局變量:任何變量如果未經聲明就賦值,此變量為全局對象所有

    eg: a = 123;

    var a = b =123;

  2、一切聲明的全局變量,全是window的屬性,一切定義在全局上的變量,都歸window所有(window等價於全局)

    eg:    console.log(a)   等價於  console.log(window.a);

    舉個例子:

 

<script>

function test(){
    var a = b = 123;
}

test();
console.log(b);

</script>

其結果為:123

如果將console.log(b) 改成 console.log(a) 則會出現 “ReferenceError: a is not defined” 的錯誤。

這是因為執行test()函數時,先對  b賦值,使 b=123, 然后再 var a 進行聲明, 最后使a=b,

b在未聲明的時候進行賦值,所以為全局變量,可以在函數外訪問,而a則是局部變量,不能再函數外訪問

 

三、預編譯的兩個規則:

  a.函數聲明整體提升 :  函數聲明不管位於哪里,系統總會把聲明提升到邏輯的最前面,因此無論函數調用在聲明前或聲明后結果都一樣

  b.變量   聲明提升:會把變量的聲明提升到函數調用前面

舉兩個小例子:

 

<script>

  test();

  functiont  test(){

  console.log('a');

  }

</script>

 

 輸出的結果為: a

 

 

<script>
    console.log(a);
    var a = 123;
</script>

輸出結果為:undefined;

 

四、預編譯四部曲(函數預編譯時)

  通過下面例子進行講解

<script type="text/javascript">
    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對象 (Activation object)(執行期上下文)
AO{ }

2:找形參和變量聲明,將變量和形參名作為AO()屬性名,值為undefined
AO{
a:undefined
b:undefined
}

3.將實參值和形參值統一
AO{
a:1
b:undefined
}

4.在函數體里找函數聲明,值賦予函數體
AO{
a:function a(){}

b:undefined
d:function d(){}
}

預編譯完后進行執行:
    首先一句一句執行,執行第一句console.log(a);那么,會在AO對象中調取a,在AO對象中a等於function a(){},那么就輸出function a(){}
  然后到達第二句
var a = 123,var a 已經被提升了,所以不用管,直接到a = 123,所以,在AO對象中,a變成了123
  AO對象變成123后,再來進行執行第三句,console.log(a);那么,現在a等於123,那么就是輸出123,
  到達第四句,第四句是函數,由於函數已經被提升了,所以沒有這一步,然后再到第五句,第五句是console.(a),所以輸出還是123吧
  然后再到第六句,第六句是var b = function (){},所以就要把在AO對象中的b的屬性改為function(){}

  所以在第七句b的輸出就是function(){},第八句直接被提升了,所以不用讀了。

結果為:
function a(){}
123
123
function (){}


全局預編譯:
生成一個GO global object對象(等價於window)

例:
  
<script>
    global = 100;
    function fn(){
    console.log(global);
    global=200;
    console.log(global);
    var global=300;
}
    fn();
    var global;
</script>

 結果為:

undefined
200

執行過程:首先生成GO{
global:undefined
}
執行第一行:global = 100
執行fn()時生成AO{
global = undefined;
}


注意
  js不是全文編譯完成再執行,而是塊編譯,即一個script塊中預編譯然后執行,再按順序預編譯下一個script塊再執行
  但是此時上一個script快中的數據都是可用的了,而下一個塊中的函數和變量則是不可用的。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM