JavaScript先行編譯原理分析

來源:互聯網
上載者:User

標籤:lob   tracking   obj   複習   lang   誤區   語法錯誤   首頁   原理   

今天用了大量時間複習了範圍、先行編譯等等知識
看了非常多博文,翻了翻曾經看過的書(好像好多書都沒有講先行編譯)
發現當初認為自己學的非常明確,事實上還是存在一些思維誤區
(非常多博文具有誤導性)
今晚就整理了一下淩亂的思路
先整理一下先行編譯的知識吧,日後有時間再把範圍具體解說一下

大家要明確。這個先行編譯和傳統的編譯是不一樣的(能夠理解js先行編譯為特殊的編譯過程)
JavaScript是解釋型語言,
既然是解釋型語言,就是編譯一行。運行一行
傳統的編譯會經曆非常多步驟,分詞、解析、代碼產生什麼的
日後有時間再給大家科普
以下就給大家分享一下我所理解的JS先行編譯

JavaScript運行三部曲

指令碼運行js引擎都做了什麼呢?

  1. 文法分析
  2. 先行編譯
  3. 解釋運行

在運行代碼前。還有兩個步驟
文法分析非常easy。就是引擎檢查你的代碼有沒有什麼低級的語法錯誤
解釋運行顧名思義便是運行代碼了
先行編譯簡單理解就是在記憶體中開闢一些空間,存放一些變數與函數
理解了先行編譯對大家理解範圍相同有協助

JS先行編譯什麼時候發生

我當初思維誤區也發生在這裡
先行編譯究竟什麼時候發生
希望大家不要讓上面的運行過程讓你產生誤會,
誤以為先行編譯只發生在script內代碼塊運行前
這倒並沒有錯
先行編譯確確實實在script代碼內運行前發生了
可是它大部分會發生在函數運行前

JS先行編譯執行個體

舉例前。先來思考一下這幾個概念:

  • 變數聲明 var…
  • 函式宣告 function…
<script>    var a = 1;// 變數聲明    function b(y){//函式宣告        var x = 1;        console.log(‘so easy‘);    };    var c = function(){//是變數聲明而不是函式宣告!

! //... } b(100);</script><script> var d = 0;</script>

讓我們看看引擎對這段代碼做了什麼吧

  • 頁面產生便建立了GO全域對象(Global Object)(也就是大家熟悉的window對象)
  • 第一個指令檔載入
  • 指令碼載入完成後。分析文法是否合法
  • 開始先行編譯
    • 尋找變數聲明,作為GO屬性。值賦予undefined
    • 尋找函式宣告。作為GO屬性,值賦予函數體
//虛擬碼GO/window = {    //頁面載入建立GO同一時候。建立了document、navigator、screen等等屬性。此處省略    a: undefined,    c: undefined。    b: function(y){        var x = 1;        console.log(‘so easy‘);    }}
  • 解釋運行代碼(直到運行函數b)
//虛擬碼GO/window = {    //變數隨著運行流得到初始化    a: 1,    c: function(){        //...    },    b: function(y){        var x = 1;        console.log(‘so easy‘);    }}
  • 運行函數b之前。發生先行編譯
    • 建立AO使用中的物件(Active Object)
    • 尋找形參和變數聲明,值賦予undefined
    • 實參值賦給形參
    • 尋找函式宣告,值賦予函數體
//虛擬碼AO = {    //建立AO同一時候。建立了arguments等等屬性。此處省略    y: 100,    x: undefined}
  • 解釋運行函數中代碼
  • 第一個指令檔運行完成。載入第二個指令檔
  • 第二個指令檔載入完成後,進行文法分析
  • 文法分析完成。開始先行編譯
    • 反覆最開始的先行編譯步驟……

大家要注意,
先行編譯階段發生變數聲明和函式宣告。沒有初始化行為(賦值),匿名函數不參與先行編譯
唯獨在解釋運行階段才會進行變數初始化
嗯~最後收一下尾

總結

先行編譯(函數運行前)※
1. 建立AO對象(Active Object)
2. 尋找函數形參及函數內變數聲明。形參名及變數名作為AO對象的屬性,值為undefined
3. 實參形參相統一,實參值賦給形參
4. 尋找函式宣告,函數名作為AO對象的屬性,值為函數引用

先行編譯(指令碼代碼塊script運行前)
1. 尋找全域變數聲明(包含隱式全域變數聲明。省略var聲明),變數名作全域對象的屬性,值為undefined
3. 尋找函式宣告。函數名作為全域對象的屬性,值為函數引用

理解了先行編譯對理解提升行為,this指向,範圍及效能等問題都有非常大協助
以後我也會總結這些問題

==首頁傳送門==

JavaScript先行編譯原理分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.