let & const —— ES6基礎總結(二)

前言

在JS中,var早已深刻人心,所以本文將再也不贅述,僅在必要時拉出來溜溜。html

聲明方式 變量提高 暫時性死區 重複聲明 可修改值 塊級做用域 全局變量屬於頂層對象
var
let
const 否(引用類型僅保證地址不被修改)

變量提高

a   // a is not defined
    let a = 'a'
    
    b  // b is not defined
    const b = 'b'
    
    c   // undefined
    var c = 'c'
複製代碼

暫時性死區

在代碼塊內,使用letconst命令聲明變量以前,該變量都是不可用的。es6

其本質是,只要一進入當前做用域,所要使用的變量就已經存在了,可是不可獲取,只有等到聲明變量的那一行代碼出現,才能夠獲取和使用該變量。web

typeof a    // a is not defined
    let a = 'a'
    
    typeof b    // b is not defined
    const b = 'b'
    
    typeof c    // "undefined"
    var c = 'c'
複製代碼

如下爲幾個比較隱蔽的死區:瀏覽器

  1. 賦值閉包

    var a = a
    let b = b   // b is not defined
    複製代碼
  2. 函數參數函數

    function foo(a = b, b = 2) {
      console.log([a, b])
    }
    foo()
    複製代碼

重複聲明

let a = 'a1'
    let a = 'a2'    // Identifier 'a' has already been declared
    a   // a1
    
    const b = 'b1'
    const b = 'b2'  // Identifier 'b' has already been declared
    b   // b2
    
    var c = 'c1'
    var c = 'c2'
    c   // c2
複製代碼

修改值

let a = 'a1'
    a = 'a2'    
    a   // a2
    
    const b = 'b1'
    b = 'b2'  // Assignment to constant variable
    b   // b1
    
    var c = 'c1'
    c = 'c2'
    c   // c2
複製代碼

const 引用類型僅保證引用地址不可修改ui

const a = {
       a1: 1,
       a2: 2
    }
    a.a3 = 3
    a   // {a1: 1, a2: 2, a3: 3}
複製代碼

塊級做用域

{
        let a = 'a'     
        const b = 'b'   
        var c = 'c'
    }
    a   // a is not defined
    b   // b is not defined
    c   // c
複製代碼

全局變量再也不屬於頂層對象

頂層對象:瀏覽器中指window,Node中指globalspa

let a = 'a'
    window.a    // undefined 
    
    const b = 'b'
    window.b    // undefined 
    
    var c = 'c'
    window.c    // "c"
複製代碼

不再用擔憂手抖修改了頂層對象~3d

解決的問題

  1. 內層變量覆蓋外層變量;code

  2. 用來計數的循環變量變爲全局變量;

    1. 上面代碼中,變量j是let聲明的,當前的j只在本輪循環有效,因此每一次循環的j其實都是一個新的變量,那麼若是每一輪循環的變量j都是從新聲明的,那它怎麼知道上一輪循環的值,從而計算出本輪循環的值?這是由於 JavaScript 引擎內部會記住上一輪循環的值,初始化本輪的變量j時,就在上一輪循環的基礎上進行計算。
    1. for循環還有一個特別之處,就是設置循環變量的那部分是一個父做用域,而循環體內部是一個單獨的子做用域。

  3. 閉包與垃圾回收;

    有塊級做用域

    有塊級做用域

    無塊級做用域

    無塊級做用域

  4. 再也不須要使用當即執行函數,減小代碼冗餘提高可讀性;

  5. 容許在塊級做用域中聲明函數,函數聲明語句的行爲相似於let;

    原來,若是改變了塊級做用域內聲明的函數的處理規則,顯然會對老代碼產生很大影響。爲了減輕所以產生的不兼容問題,ES6 在附錄 B裏面規定,瀏覽器的實現能夠不遵照上面的規定,有本身的行爲方式

    1.容許在塊級做用域內聲明函數。

    2.函數聲明相似於var,即會提高到全局做用域或函數做用域的頭部。

    3.同時,函數聲明還會提高到所在的塊級做用域的頭部。

    注意,上面三條規則只對 ES6 的瀏覽器實現有效,其餘環境的實現不用遵照,仍是將塊級做用域的函數聲明看成let處理。

參考

  1. ECMAScript 6 入門

  2. 你不知道的JavaScript(上)

小結

本文主要介紹了letconstvar定義變量的區別以及優勢。推薦我用了兩個月的時間才理解 let這篇文章,供你們思考。

以前聲明變量只能使用varfunction,如今ES6添加了letconstimportclass4種方式(importclass 後續也會一一總結),因此如今總共有6種聲明變量的方式。SO聲明變量,請合理選擇。

感謝閱讀,若有問題,歡迎指正。

最最最最最後,在這四天的五一小長假裏,爲你們獻上美景 —— 摩洛哥藍色小鎮🇲🇦祝你們五一愉快呦~

摩洛哥藍色小鎮
相關文章
相關標籤/搜索