ES6入個門

2020-07-07

阮師傅的ES6教程整理下來的;

  • ES、JS關系
    • JS 1996年 Netscape創立,並交ECMA標準化;
    • ECMA-262 規定瀏覽器腳本語言標準,ECMAScript 1.0;
    • ES 是 JS 的規格,JS 是 ES 的實現;
  • ES6、ES2015關系
    • ES2015 - ES6、ES2016 - ES6.1、ES2017 - ES6.2;
    • 下壹代JS語言;
  • 語法提案
    • 向TC39標準委員會提交;
    • GitHub.com/tc39/ecma262
    • Stage 0-Strawman、1-Proposal、2-Draft、3-Candidate、4-Finished;
  • 歷史
    • ECMAScript 1.0 - 1997年,2.0-1998年6月,3.0-1999年12月(入門);
    • 2007、2008年,ES4因激進大部分內容沒有通過(產生ES3.1 代號Harmony),ES6制定起點是2000年;
    • 2009年12月ES5.0,Harmony 分裂,JavaScript.next 演變 ES6;
    • ···

let、const

  • let

    • 代碼塊內有效;
    • for 設置循環處是代碼塊內的父作用域;
    • 不存在變量提升;
    • 暫時性死區(temporal dead zone,TDZ);
      • typeof 不再安全;
      • ReferenceError 拋錯;
    • 不允許重復聲明;
  • 塊級作用域

    • ES5 只有全局和函數作用域;
    • 為什麼需要?
      • 內層變量可能會覆蓋外層變量;
      • 用來計數的循環變量泄露為全局變量;
    • 外層代碼塊不受內層代碼塊的影響;
    • ES6 允許塊級作用域的任意嵌套;
    • 廣泛應用的匿名立即執行函數表達式(匿名 IIFE)不再必要了;
    • ES6 規定,塊級作用域之中,函數聲明語句的行為類似於let,在塊級作用域之外不可引用;
    • ES6 的塊級作用域必須有大括號,如果沒有大括號,JavaScript 引擎就認為不存在塊級作用域;
    • 'use strict'嚴格模式下,函數只能聲明在當前作用域的頂層
      • 區分:函數聲明、函數表達式的區別
  • const

    • 聲明不賦值會拋錯:SyntaxError: Missing initializer in const declaration

    • 同let壹樣塊級區域有效、存在暫時性死區;

    • 並不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動;

    • 簡單類型不得改動,復合類型數據,變量指向的內存地址,保存的只是壹個指向實際數據的指針,const只能保證這個指針是固定的(即總是指向另壹個固定的地址),至於它指向的數據結構是不是可變的,就完全不能控制了。

    • 應該使用Object.freeze方法,凍結對象;

    • 徹底凍結

      • 1
        2
        3
        4
        5
        6
        7
        8
        var constantize = (obj) => {
        Object.freeze(obj);
        Object.keys(obj).forEach( (key, i) => {
        if ( typeof obj[key] === 'object' ) {
        constantize( obj[key] );
        }
        });
        };
  • ES聲明變量有6種方法;

  • 頂層對象

    • 瀏覽器:window
    • Node:global
    • ES6 為了改變這壹點,壹方面規定,為了保持兼容性,var命令和function命令聲明的全局變量,依舊是頂層對象的屬性;另壹方面規定,let命令、const命令、class命令聲明的全局變量,不屬於頂層對象的屬性。也就是說,從 ES6 開始,全局變量將逐步與頂層對象的屬性脫鉤。
    • ES2020 規定了 globalThis

解構

  • 數組解構

    • 只要某種數據結構具有 Iterator 接口,都可以采用數組形式的解構賦值。

    • 默認值:解構允許指定默認值,ES6 內部使用嚴格相等運算符(===),判斷壹個位置是否有值。所以,只有當壹個數組成員嚴格等於undefined,默認值才會生效;

    • 1
      2
      3
      4
      let [x = 1] = [undefined];
      x // 1
      let [x = 1] = [null];
      x // null
    • 如果默認值是壹個表達式,那麼這個表達式是惰性求值的;

  • 對象解構

    • 數組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值;
    • 如果解構失敗,變量的值等於undefined
    • let { foo: baz } = { foo: 'aaa', bar: 'bbb' };如果變量名與屬性名不壹致,必須寫成這樣,對象的解構賦值的內部機制,是先找到同名屬性,然後再賦給對應的變量。真正被賦值的是後者,而不是前者(前者為模式,後者是變量);
    • 對象的解構賦值可以取到繼承的屬性;
    • 對象的解構也可以指定默認值
    • 註意點:
      • 如果要將壹個已經聲明的變量用於解構賦值,大括號會被理解為代碼塊;
      • 解構賦值允許等號左邊的模式之中,不放置任何變量名;
      • 由於數組本質是特殊的對象,因此可以對數組進行對象屬性的解構;
  • 字符串的解構賦值;

  • undefined、null 無法解構;

  • 用途

    • 交換變量的值
    • 從函數返回多個值
    • 函數參數的定義
    • 提取 JSON 數據
    • 函數參數的默認值
    • 遍歷 Map 結構
      • 任何部署了 Iterator 接口的對象,都可以用for...of循環遍歷
    • 輸入模塊的指定方法

字符串擴展

  • Unicode

    • Unicode 可以使用大括號\u{20BB7} 表示更多字符

    • 1
      '\u{1F680}' === '\uD83D\uDE80' // true
    • 1
      2
      3
      4
      5
      '\z' === 'z'  // true
      '\172' === 'z' // true
      '\x7A' === 'z' // true
      '\u007A' === 'z' // true
      '\u{7A}' === 'z' // true
  • 字符串遍歷

    • ES6 字符串 有 Iterator 遍歷接口 可以被 for of 循環遍歷;
    • 可以識別大於0xFFFF的碼點;
  • U+2028、U+2029

    • JavaScript 規定有5個字符,不能在字符串裏面直接使用,只能使用轉義形式:
      • U+005C:反斜杠(reverse solidus)
      • U+000D:回車(carriage return)
      • U+2028:行分隔符(line separator)
      • U+2029:段分隔符(paragraph separator)
      • U+000A:換行符(line feed)
    • 字符串裏面不能直接包含反斜杠,壹定要轉義寫成\\或者\u005c
  • JSON.stringify

    • ES2019 改變了JSON.stringify()的行為。如果遇到0xD8000xDFFF之間的單個碼點,或者不存在的配對形式,它會返回轉義字符串,留給應用自己決定下壹步的處理;
  • 字符模版 `

    • 普通字符串;
    • 多行字符串;
    • 嵌入變量;
    • trim 消除首尾換行;
    • 模板字符串甚至還能嵌套;
  • 標簽模版 Tagged template

    • func`abc ${123} 123`
    • func([‘abc ‘,’ 123’],123)
    • 用於 i18n 或者 過濾HTML
    • 有 raw 屬性
  • 模版字符限制

… 未完


Comments: