快速理解javascript解析流程

javascript 執行分兩步 1.預解析 2執行 執行的都是解析後的代碼

1. 廢話很少說,上代碼。

console.log(a);
var a = 10
複製代碼
  • 先想一想這個執行結果是什麼?

js解析完成

a = undefined
    console.log(a);  // undefined
    a = 10;
複製代碼
  • 執行結果是 undefined 這個過程叫變量提高。解析時遇到var 就會提高上去但並無賦值。

2. 變形

console.log(b);
    console.log(c);
    
    function b() {
        console.log("b");
    }
    
    var c = function() {
        console.log("c");
    }
複製代碼

js解析完成

function b() {
        console.log("b");
    }
    c = undefined;
    console.log(b);  // function b() { console.log("b") }
    console.log(c);  // undefined
    c = function() {
        console.log("c");
    }
複製代碼
  • 一樣是函數,帶var函數的函數表達式跟定義一個變量都有相同效果。提高並不賦值。 而函數則不一樣,函數聲明會直接提高到頂部。

咱們記住兩點 在預解析階段 有函數提高和變量提高兩個動做。javascript

3. 繼續增強

(functino(){
        console.log(a);  // undefined
        var a = 10;
    })()
    
    function start(){
        console.log(b);  // function b() { console.log("b") }
        console.log(c);  // undefined
        
        function b() {
            console.log("b");
        }
        
        var c = function() {
            console.log("c");
        }
    }
    start();
複製代碼

變量提高發生在當前的函數做用域內。 自執行函數和函數都有提高過程。java

4. 無var的狀況

(function(){
        b = 10;
    })()
    
    console.log(b);
複製代碼

js 解析完成

(function(){
        b = 10;
    })()
    console.log(b); // 10
複製代碼

沒有聲明的變量b在解析階段並無提高,js執行器在發現b沒有在當前做用域聲明時會在執行階段提高到全局。因此外面能夠訪問到 。 若是在執行階段提早打印b會直接報錯中止運行。bash

5. 特殊狀況

5.1 例1異步

(function(){
        console.log(b);       
        var b = 10;
        function b(){
            console.log("fn");
        }
        console.log(b);
    })()
複製代碼

解析完成

(function(){
        function b(){
            console.log("fn");
        }
        
        console.log(b); // function b(){console.log("fn"); }
        b = 10;
        console.log(b); // 10
    })()
複製代碼

當函數生命和var聲明同時存在的時候 函數聲明優先級高 這個要注意函數

5.2 例2spa

function start(b){
        start = 10;
        console.log(start);
        console.log(b);
        b = 10;
    }
    start();
    console.log(b);
複製代碼

解析完成

function start(){
        b = undefined;
        start = 10;
        console.log(start); // function start(b){ ... }
        console.log(b); // undefined
        b = 10;
    }
    start();
    console.log(b); // err b is not defined
複製代碼

在函數內部有參數時 b 就會聲明在函數內部。 而給函數名自己賦值是無效的。code

結束


還有更多js的解析過程須要你們發現。例如異步代碼。setTimeout Promise 等等執行過程 這裏列舉在函數解析過程中的常見問題。好比 let const 就沒有提高過程。ip

相關文章
相關標籤/搜索