有關您的 javascript 函數編譯(上)

懶編譯您 javascript

marja 的 parsing javascript better lazy than eager

解析什麼是解析

  1. 解析 javascript code 爲 AST 和 Scope 作用域
    今天我們之關心這部分內容
  2. 生成字節碼, 這個字節碼用於解釋器
  3. 優化編譯爲機器碼在 電腦上執行

我們通常認爲 javascript 是一門解釋性還是編譯的語言呢

sum(1,2)

function sum(a,b){
    return a + b;
}
function foo(){
    let a = 0;
    if(a == 0){
        let b = "bar";
        return a;
    }
}

從上面代碼運行沒有問題來看 javascript 應該屬於編譯語言。

準備用 mac 的 keynote 畫樹形結構圖,感覺連線有點費勁放棄了。

  1. 第一層是 foo 函數對應節點 FunctionIterial
let a = 0;
  1. 當我們 聲明創建一個變量同時就生成一個變量的代理。 然後就是我們的賦值語句。分別是變量代理和
if(a == 0){
    let b = "bar";
    return a;
}
  1. 看一下我們的 條件語句
    因爲沒有 else 只有 if 所以就走 then。

作用域分析

# 爲什麼我們需要關注解析

因爲我們parsing

不同的瀏覽器對lazy定義也不同,由於 javascript 本身並沒有 spec 來定義lazy

#### V8 有兩種有兩種解析模式

  • eager parser 進行完全的解析, 構建 AST、 構建作用域, 檢查語法錯誤。
  • lazy preParser 構建 scope(作用域)而不構建 AST,

lazy 和 eager

let a = 0;
//IIFE (immediately invoked function express)
(function() eager() { // stuff })();

function lazy(){ //stuff }
lazy();
  1. 通過()()包裹函數是立即執行函數
  2. 即使 lazy 在最頂層被定義,lazy 也是 懶函數,只有在調用纔會執行。
!function eager2(){ // stuff },function eager3(){ // stuff }

在函數前面添加 ! 表示這個函數是立即執行函數, 後面通過逗號間隔的也同樣是立即執行函數。

也有一些特殊的情況

let f1 = function lazy() { // stuff }
let f2 = function lazy(){ // stuff }()

f1 變量接受 lazy 函數作爲值,作爲懶函數來處理
f2 接受這個函數執行的結果作爲 f2,首先我們看 lazy 應該是懶函數,但是他被立即執行了。

那麼 懶函數跟我們有關係嗎?

因爲不是所有加載 javascript 都會被執行的,所以我們需要賴 加載來提高效率。

  • 如果一個 eager 立即編譯函數 沒有被 調用, 這就是一種浪費。
  • 如果 一個懶函數被 執行了,當然也是一種資源的浪費,因爲我們將這個函數編譯了兩次,第一次 編譯可能需要 0.5 ,第二次又進行 了編譯,所以一共 1.5 時間。

強制 函數爲立即編譯模式

    (function a(){})

Optimize.js 將那些將會在引用中(上面的情況) 進行包裹讓他變成立即編譯函數

ctxt 分配,賴函數我們需要分配 ctxt

let f = (function outer(){
    let a = 20;
    function inner(){ return 1 }
    return inner;
})();

console.log(f());

我們看一看上面的代碼的 f 接收一個立即 編譯函數的返回值,返回值是一個懶函數,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章