前言 之前翻博客園的時候,看到有人朋友分享阿裡巴巴的面試題,其中有一道題就是關於ES6轉ES5 原理的,當時我看到感覺到自己離去阿裡巴巴的路還很遠啊,像我們大部分做開發的時候,都只知其然不知 其所以然,本著好學的態度我也去網上搜了下關於Babel es6轉es5的原理,但是很多都是枯燥難懂,整理了一 ...
前言
之前翻博客園的時候,看到有人朋友分享阿裡巴巴的面試題,其中有一道題就是關於ES6轉ES5
原理的,當時我看到感覺到自己離去阿裡巴巴的路還很遠啊,像我們大部分做開發的時候,都只知其然不知
其所以然,本著好學的態度我也去網上搜了下關於Babel es6轉es5的原理,但是很多都是枯燥難懂,整理了一下午
把自己的收穫和大家分享一下,有不對的地方請各位大神指正.
Babel運行原理
再說es6怎樣轉es5之前我們首先要來說一下Babel的運行原理,知道運行原理,我們也就不難理解
為什麼Babel能這麼強大.
Babel工作分為三個階段:
1.解析:將代碼字元串解析成抽象語法樹
2.變換:將抽象語法樹
3.根據變換後的抽象語法樹再生成代碼字元串
舉個例子:
if(1>0){ alert('hi') }
用圖像更簡單地表達上面的結構:
第1步轉換的過程中可以驗證語法的正確性,同時由字元串變為對象結構後更有利於精準地分析以及進行代碼結構調整。
第2步原理,就是遍歷這個對象所描述的抽象語法樹,遇到哪裡需要做一下改變,就直接在對象上進行操作,比如我把IfStatement給改成WhileStatement就達到了把條件判斷改成迴圈的效果。
第3步,遞歸遍歷這顆語法樹,然後生成相應的代碼
第二步和第三步大家都很好理解,現在我來著重講解第一步.
解析第一步分為兩個步驟:
1.分詞:將整個代碼字元串分割成 語法單元 數組
2.語義分析:在分詞結果的基礎之上分析 語法單元之間的關係
分詞的過過程從邏輯來講並不難解釋,但是這是個精細活,要考慮清楚所有的情況。還是以一個代碼為例:
if (1 > 0) { alert("if \"1 > 0\""); }
我們希望得到的分詞是:
'if' ' ' '(' '1' ' ' '>' ' ' ')' ' ' '{' '\n ' 'alert' '(' '"if \"1 > 0\""' ')' ';' '\n' '}'
這拆分過程其實沒啥可取巧的,就是簡單粗暴地一個字元一個字元地遍歷,然後分情況討論,整個實現方法就是順序遍歷和大量的條件判斷.
語義分析就是把辭彙進行立體的組合,確定有多重意義的詞語最終是什麼意思、多個詞語之間有什麼關係以及又應該再哪裡斷句等。
語義分析的過程又是個遍歷語法單元的過程,不過相比較而言更複雜,因為分詞過程中,每個語法單元都是獨立平鋪的,而語法分析中,語句和表達式會以樹狀的結構互相包含。針對這種情況我們可以用棧,也可以用遞歸來實現。
結語
真正看下來,其實沒有哪個地方的原理特別高深莫測,就是精細活,需要考慮到各種各樣的情況。總之要做一個完整的語法解釋器需要的是十分的細心與耐心。
本篇博客是根據 百度外賣前端 進行的總結原博客 https://zhuanlan.zhihu.com/p/27289600