JS中let和var的區別

1. 定義變量

  • 聲明語法
    var upperA = 'A';
    let upperB = 'B';
    const upperC = 'C';
  • 只聲明不初始化的結果,【 const定義的常量不能夠修改,並且必須初始化。
    // var 聲明變量
    var upperA;
    console.log('打印大寫的A:%s', upperA);
    // 結果:打印大寫的A:undefined
    
    // let 聲明變量
    var upperB;
    console.log('打印大寫的B:%s', upperB);
    // 結果:打印大寫的B:undefined
    
    // const 聲明常量
    const upperC;
    console.log('打印大寫的C:%s', upperC);
    // 錯誤:SyntaxError: Missing initializer in const declaration
  • 聲明後值是否可修改,【 const定義的常量不能夠修改,並且必須初始化。
    // var 聲明變量初始化並修改值
    var upperA = 'A';
    console.log('打印upperA:%s', upperA);
    // 結果:打印upperA:A
    upperA = 'LetterA';
    console.log('打印upperA:%s', upperA);
    // 結果:打印upperA:LetterA
    
    // let 聲明變量初始化並修改值
    var upperB = 'B';
    console.log('打印大寫的B:%s', upperB);
    // 結果:打印upperB:B
    upperB = 'LetterB';
    console.log('打印大寫的B:%s', upperB);
    // 結果:打印upperB:LetterB
    
    // const 聲明常量初始化並修改值
    const upperC = 'C';
    console.log('打印upperC:%s', upperC);
    // 結果:打印upperC:C
    upperC = 'LetterC';
    console.log('打印upperC:%s', upperC);
    // 錯誤:TypeError: Assignment to constant variable.

2. 變量提高

  • 瀏覽器在運行代碼以前會進行預解析,首先解析函數聲明,定義變量,解析完以後再對函數、變量進行運行、賦值等
    不論var聲明的變量處於當前做用域的第幾行,都會提高到做用域的頭部。
    var 聲明的變量會被提高到做用域的頂部並初始化爲undefined,而let聲明的變量不會被提高到做用域的頂部。
    console.log('打印upperA:%s', upperA);
    // 結果:打印upperA:undefined
    console.log('打印upperB:%s', upperB);
    // 錯誤:ReferenceError: upperB is not defined
    var upperA = 'A';
    let upperB = 'B';

3. 是否容許重複聲明同一個變量

  • ** var容許在相同做用域內,重複聲明同一個變量,後面聲明的變量會覆蓋前面聲明的變量。
    ** let不容許在相同做用域內,重複聲明同一個變量。
    var upperA = 'A';
    let upperB = 'B';
    // 重複聲明
    var upperA = 'LetterA';
    let upperB = 'LetterB';
    console.log('打印upperA:%s', upperA);
    console.log('打印upperB:%s', upperB)
    // 錯誤:SyntaxError: Identifier 'upperB' has already been declared

4. 做用域

  • 在ES6以前,咱們都是用var來聲明變量,並且JS只有函數做用域和全局做用域,沒有塊級做用域,因此{}限定不了var聲明變量的訪問範圍。
    // ---------- 例如: ----------
    {
        var upperA = 'A';
    }
    console.log('打印upperA:%s', upperA);
    # 結果: 打印upperA:A
    
    // ---------- ES6新增的let,能夠聲明塊級做用域的變量。----------
    {
        let upperB = 'B';
    }
    console.log('打印upperB:%s', upperB);
    // 錯誤: ReferenceError: upperB is not defined

5. let配合for循環的獨特應用

  • let很是適合用於 for循環內部的塊級做用域。
    ** JS中的for循環體比較特殊,每次執行都是一個全新的獨立的塊做用域,用let聲明的變量傳入到 for循環體的做用域後,不會發生改變,不受外界的影響。
    // ---------- 看一個常見的面試題目: ----------
    for (var i = 0; i <10; i++) {  
        setTimeout(function() {    // 同步註冊回調函數到 異步的 宏任務隊列。
            console.log(i);        // 執行此代碼時,同步代碼for循環已經執行完成
        }, 0);
    }
    // 輸出結果:10   共10個
    // 這裏面的知識點: JS的事件循環機制,setTimeout的機制等
    
    // ---------- 若是把 var改爲 let聲明:----------
    // i雖然在全局做用域聲明,可是在for循環體局部做用域中使用的時候,變量會被固定,不受外界干擾。
    for (let i = 0; i < 10; i++) { 
        setTimeout(function() {
            console.log(i);    //  i 是循環體內局部做用域,不受外界影響。
        }, 0);
    }
    // 輸出結果:0  1  2  3  4  5  6  7  8 9
相關文章
相關標籤/搜索