ES6 —— ES12

ECMAScript 是一種由 Ecma 國際(前身為歐洲計算機制造商協(xié)會)通過 ECMA-262 標準化的腳本程序設計語言薯演。這種語言在萬維網(wǎng)上應用廣泛,它往往被稱為 JavaScriptJScript允瞧,所以它可以理解為是 JavaScript 的一個標準翰守,但實際上后兩者是 ECMA-262 標準的實現(xiàn)和擴展库糠。

ES6(ES2015)

  1. letconst

    var let const
    變量提升 × ×
    全局變量 × ×
    重復聲明 × ×
    重新賦值 ×
    暫時性死區(qū) ×
    塊作用域 ×
    只聲明不初始化 ×

    暫時性死區(qū)(TDZ):ES6 明確規(guī)定沙兰,如果區(qū)塊中存在 let 命令,這個區(qū)塊對這些命令聲明的變量二打,從一開始就形成了封閉作用域县忌。只要一進入當前作用域,所要使用的變量就已經(jīng)存在了继效,但是不可獲取症杏,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量瑞信。

    let厉颤、const 聲明的變量 ,不會綁定在 window 上。

  2. 類(Class
    ES6 之前,如果我們要生成一個實例對象拇惋,傳統(tǒng)的方法就是寫一個構造函數(shù),例子如下:

    function Person(name, age) {
        this.name = name
        this.age = age
    }
    Person.prototype.information = function () {
        return 'My name is ' + this.name + ', I am ' + this.age
    }
    

    但是在 ES6 之后帜乞,我們只需要寫成以下形式:

    class Person {
        constructor(name, age) {
            this.name = name
            this.age = age
        }
        information() {
            return 'My name is ' + this.name + ', I am ' + this.age
        }
    }
    
  3. 箭頭函數(shù)(Arrow function)

  4. 函數(shù)參數(shù)默認值(Function parameter defaults)

  5. 模板字符串(Template string)

  6. 解構賦值(Destructuring assignment)

  7. 模塊化(Module)

  8. 擴展操作符(Spread operator)

  9. Promise
    PromiseES6 提供的一種異步解決方案,比回調函數(shù)更加清晰明了筐眷。
    所謂 Promise黎烈,簡單說就是一個容器,里面保存著某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說照棋,Promise 是一個對象资溃,從它可以獲取異步操作的消息。
    Promise 提供統(tǒng)一的 API烈炭,各種異步操作都可以用同樣的方法進行處理溶锭。Promise 對象有以下兩個特點:

    • 對象的狀態(tài)不受外界影響。Promise 對象代表一個異步操作符隙,有三種狀態(tài):Pending(進行中)趴捅、Resolved(已完成,又稱 Fulfilled)和 Rejected(已失斉摺)驻售。只有異步操作的結果,可以決定當前是哪一種狀態(tài)更米,任何其他操作都無法改變這個狀態(tài)。
    • 一旦狀態(tài)改變毫痕,就不會再變征峦,任何時候都可以得到這個結果。Promise 對象的狀態(tài)改變消请,只有兩種可能:從 Pending 變?yōu)?Resolved 和從 Pending 變?yōu)?Rejected栏笆。

    缺點:首先,無法取消 Promise臊泰,一旦新建它就會立即執(zhí)行蛉加,無法中途取消。其次缸逃,如果不設置回調函數(shù)针饥,Promise 內部拋出的錯誤,不會反應到外部需频。第三丁眼,當處于 Pending 狀態(tài)時,無法得知目前進展到哪一個階段(剛剛開始還是即將完成)昭殉。

    var promise = new Promise(function(resolve, reject) {
      // ... some code
      if (/* 異步操作成功 */){
        // 若 resolve(value); 后面還有語句苞七,也會同步執(zhí)行。若為 return resolve(value); 則后面的語句不會執(zhí)行
        resolve(value);
      } else {
        reject(error);
      }
    })
    
    promise.then(function(value) {
      // success
    }, function(error) {
      // failure
    })
    
    • Promise.all():用于將多個 Promise 實例(如果不是挪丢,就會先調用 Promise.resolve 方法蹂风,將參數(shù)轉為 Promise 實例),包裝成一個新的 Promise 實例乾蓬。
      (1)只有這幾個實例的狀態(tài)都變成 resolved惠啄,p 的狀態(tài)才會變成 resolved,此時傳遞給 p 的回調函數(shù)的參數(shù)為返回值組成的數(shù)組。
      (2)只要實例中有一個被 rejected礁阁,p 的狀態(tài)就變成 rejected巧号,此時第一個被 reject 的實例的返回值,會傳遞給 p 的回調函數(shù)姥闭。如果 p2 沒有自己的 catch 方法丹鸿,就會調用 Promise.all()catch方法。

    • Promise.allSettled():接受一組 Promise 實例作為參數(shù)棚品,包裝成一個新的 Promise 實例靠欢。只有等到所有這些參數(shù)實例都返回結果,不管是 fulfilled 還是 rejected铜跑,包裝實例才會結束门怪。返回值 allSettledPromise,狀態(tài)只可能變成 fulfilled锅纺。它的監(jiān)聽函數(shù)接收到的參數(shù)是數(shù)組 results(含 fulfilled 的結果 or rejected 的結果)掷空。

    • Promise.race():接受一組 Promise 實例作為參數(shù),包裝成一個新的 Promise 實例囤锉。var p = Promise.race([p1, p2, p3]) 只要 p1坦弟、p2、p3 之中有一個實例率先改變狀態(tài)官地,p 的狀態(tài)就跟著改變酿傍。那個率先改變的 Promise 實例的返回值,就傳遞給 p 的回調函數(shù)驱入。

    • Promise.any():接受一組 Promise 實例作為參數(shù)赤炒,包裝成一個新的 Promise 實例。只要參數(shù)實例有一個變成 fulfilled 狀態(tài)亏较,包裝實例就會變成 fulfilled 狀態(tài)莺褒;如果所有參數(shù)實例都變成 rejected 狀態(tài),包裝實例就會變成 rejected 狀態(tài)宴杀,參數(shù)為成員錯誤結果數(shù)組癣朗。

    • Promise.resolve():將現(xiàn)有對象轉為 Promise 對象。

      Promise.resolve('foo')
      // 等價于
      new Promise(resolve => resolve('foo'))
      
    • Promise.reject():將現(xiàn)有對象轉為 Promise 對象旺罢,該實例的狀態(tài)為 rejected旷余。

      var p = Promise.reject('出錯了');
      // 等價于
      var p = new Promise((resolve, reject) => reject('出錯了'))
      
    • done():總是處于回調鏈的尾端,保證拋出任何可能出現(xiàn)的錯誤

    • finally():用于指定不管 Promise 對象最后狀態(tài)如何扁达,都會執(zhí)行的操作正卧。它與 done 方法的最大區(qū)別,它接受一個普通的無參數(shù)的回調函數(shù)作為參數(shù)跪解,該函數(shù)不管怎樣都必須執(zhí)行炉旷,與狀態(tài)無關,不依賴于 Promise 的執(zhí)行結果。

    • Promise.try():讓同步函數(shù)同步執(zhí)行窘行,異步函數(shù)異步執(zhí)行饥追,并且讓它們具有統(tǒng)一的 API

      const f = () => console.log('now');
      Promise.try(f);
      console.log('next');
      // now
      // next
      
  10. for…of

    const array1 = ['a', 'b', 'c']
    for (const element of array1) {
          console.log(element)
    }
    

    for ... in ; for ... of 區(qū)別

    • for ... in 獲取的是對象的鍵名;for ... of 遍歷獲取的是對象的鍵值
    • for ... in 會遍歷對象的整個原型鏈罐盔,性能非常差但绕,不推薦使用;而 for ... of 只遍歷當前對象惶看,不會遍歷原型鏈
    • 對于數(shù)組的遍歷捏顺,for ... in 會返回數(shù)組中所有可枚舉的屬性(包括原型鏈上可枚舉的屬性);for ... of 只返回數(shù)組的下標對應的屬性值
    • 對于普通對象纬黎,沒有部署原生的 iterator 接口幅骄,直接使用 for...of 會報錯,也可以使用 Object.keys(obj) 方法將對象的鍵名生成一個數(shù)組本今,然后遍歷這個數(shù)組
    • forEach 循環(huán)無法中途跳出拆座,break 命令或 return 命令都不能奏效;for...of 循環(huán)可以與 break冠息、continue 和 return 配合使用懂拾,跳出循環(huán)
    • for...in 循環(huán)主要是為了遍歷對象而生,不適用于遍歷數(shù)組铐达;for...of 循環(huán)可以用來遍歷數(shù)組、類數(shù)組對象檬果,字符串瓮孙、Set、Map 以及 Generator 對象
  11. Symbol
    symbol 是一種基本數(shù)據(jù)類型选脊,表示獨一無二的值杭抠。Symbol() 函數(shù)會返回 symbol 類型的值,該類型具有靜態(tài)屬性和靜態(tài)方法恳啥。
    每個從 Symbol() 返回的 symbol 值都是唯一的偏灿。一個 symbol 值能作為對象屬性的標識符;這是該數(shù)據(jù)類型僅有的目的钝的。

    const symbol1 = Symbol();
    const symbol2 = Symbol(42);
    const symbol3 = Symbol('foo');
    
    console.log(typeof symbol1);  // "symbol"
    console.log(symbol3.toString());  // "Symbol(foo)"
    console.log(Symbol('foo') === Symbol('foo'));  // false
    
  12. 迭代器(Iterator)/ 生成器(Generator)
    迭代器(Iterator)是一種迭代的機制翁垂,為各種不同的數(shù)據(jù)結構提供統(tǒng)一的訪問機制。任何數(shù)據(jù)結構只要內部有 Iterator 接口硝桩,就可以完成依次迭代操作沿猜。
    一旦創(chuàng)建,迭代器對象可以通過重復調用 next() 顯式地迭代碗脊,從而獲取該對象每一級的值啼肩,直到迭代完,返回 { value: undefined, done: true }祈坠。

    function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
        for (let i = start; i < end; i += step) {
            yield i;
        }
    }
    var a = makeRangeIterator(1,10,2)
    a.next() // {value: 1, done: false}
    a.next() // {value: 3, done: false}
    a.next() // {value: 5, done: false}
    a.next() // {value: 7, done: false}
    a.next() // {value: 9, done: false}
    a.next() // {value: undefined, done: true}
    
  13. Set / WeakSet
    Set 對象允許你存儲任何類型的唯一值儒陨,無論是原始值或者是對象引用。

    const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
    console.log([...new Set(numbers)])  // [2, 3, 4, 5, 6, 7, 32]
    

    WeakSet 結構與 Set 類似州叠,但區(qū)別有以下兩點:

    • WeakSet 對象中只能存放對象引用逆甜,不能存放值斟或,而 Set 對象都可以亚享。
    • WeakSet 對象中存儲的對象值都是被弱引用的亭罪,如果沒有其他的變量或屬性引用這個對象值,則這個對象值會被當成垃圾回收掉箩祥。正因為這樣肆氓,WeakSet 對象是無法被枚舉的,沒有辦法拿到它包含的所有元素蕉陋。
    const ws = new WeakSet()
    const obj = {}
    const foo = {}
    
    ws.add(window)
    ws.add(obj)
    
    ws.has(window)  // true
    ws.has(foo)  // false, 對象 foo 并沒有被添加進 ws 中 
    
    ws.delete(window)  // 從集合中刪除 window 對象
    ws.has(window)  // false, window 對象已經(jīng)被刪除了
    
    ws.clear()  // 清空整個 WeakSet 對象
    
  14. Map / WeakMap
    Map 對象保存鍵值對。任何值(對象或者原始值) 都可以作為一個鍵或一個值惋嚎。甚至可以使用 NaN 來作為鍵值。

    const myMap = new Map();
    myMap.set(NaN, "not a number");
    myMap.get(NaN);  // "not a number"
    
    const otherNaN = Number("foo");
    myMap.get(otherNaN);  // "not a number"
    

    WeakMap 對象是一組鍵 / 值對的集合站刑,其中的鍵是弱引用的另伍。其鍵必須是對象,而值可以是任意的绞旅。跟 Map 的區(qū)別與 SetWeakSet 的區(qū)別相似摆尝。

    const o1 = {};
    const o2 = function(){};
    const o3 = window;
    
    const wm1 = new WeakMap();
    wm1.set(o1, 37);
    wm1.has(o1);  // true
    wm1.delete(o1);
    wm1.has(o1);  // false
    
    wm1.set(o2, "azerty");
    wm1.get(o2);  // "azerty"
    wm1.has(o2);  // true
    
    const wm2 = new WeakMap();
    wm2.set(o1, o2);  // value可以是任意值,包括一個對象
    wm2.get(o2);  // undefined,wm2中沒有o2這個鍵
    wm2.has(o2);  // false
    
    wm2.set(o3, undefined);
    wm2.get(o3);  // undefined,值就是undefined
    wm2.has(o3);  // true (即使值是undefined)
    
    wm2.set(wm1, wm2);  // 鍵和值可以是任意對象,甚至另外一個WeakMap對象
     
    const wm3 = new WeakMap();
    wm3.set(o1, 37);
    wm3.get(o1);  // 37
    wm3.clear();
    wm3.get(o1);  // undefined,wm3已被清空
    
  15. Proxy / Reflect
    Proxy 對象用于定義基本操作的自定義行為(如屬性查找,賦值因悲,枚舉堕汞,函數(shù)調用等)。
    Reflect 是一個內置的對象晃琳,它提供攔截 JavaScript 操作的方法讯检。這些方法與 Proxy 的方法相同琐鲁。Reflect 不是一個函數(shù)對象,因此它是不可構造的人灼。

    const observe = (data, callback) => {
      return new Proxy(data, {
            get(target, key) {
                return Reflect.get(target, key)
            },
            set(target, key, value, proxy) {
                  callback(key, value);
                  target[key] = value;
                    return Reflect.set(target, key, value, proxy)
            }
      })
    }
    
    const FooBar = { open: false };
    const FooBarObserver = observe(FooBar, (property, value) => {
      property === 'open' && value 
          ? console.log('FooBar is open!!!') 
          : console.log('keep waiting');
    });
    console.log(FooBarObserver.open)  // false
    FooBarObserver.open = true  // FooBar is open!!!
    FooBarObserver.open = false // keep waiting
    
  16. Regex對象的擴展

    • u 修飾符:
      為了處理碼點大于 \uFFFFUnicode 字符(也就是說围段,會正確處理四個字節(jié)的 UTF-16 編碼);\uD83D\uDC2A 是一個字符投放,但是 es5 不支持四個字節(jié)的 UTF-16奈泪,會將其識別成兩個字符;加了 u 修飾符之后灸芳,es6 會將其識別成一個字符涝桅。

      // i 修飾符:不區(qū)分大小寫
      /[a-z]/i.test('\u212A')  // false
      /[a-z]/iu.test('\u212A')  // true
      
    • y 修飾符:“粘連”(sticky)修飾符
      y 修飾符的作用與 g 修飾符類似,也是全局匹配烙样,后一次匹配都從上一次匹配成功的下一個位置開始冯遂。不同之處在于,g 修飾符只要剩余位置中存在匹配就可误阻,而 y 修飾符確保匹配必須從剩余的第一個位置開始债蜜,這也就是“粘連”的涵義。

      var s = 'aaa_aa_a';
      var r1 = /a+/g;
      var r2 = /a+/y;
      
      r1.exec(s) // ["aaa"]
      r2.exec(s) // ["aaa"]
      
      r1.exec(s) // ["aa"]
      r2.exec(s) // null
      
    • 查看RegExp構造函數(shù)的修飾符

      new RegExp(/abc/ig, 'i').flags  //  "i"
      
  17. Array 對象的擴展

    • Array.from()
      用于將兩類對象轉為真正的數(shù)組:類似數(shù)組的對象(array-like object)和可遍歷(iterable)的對象(包括 ES6 新增的數(shù)據(jù)結構 SetMap)究反。

      Array.from('foo')  //  ["f", "o", "o"]
      // 擴展運算符(...)也可以將某些數(shù)據(jù)結構轉為數(shù)組
      [ ...document.querySelectorAll('div') ]  //  NodeList對象
      Array.from({ length: 3 })  //  [ undefined, undefined, undefined ]
      Array.from([1, 2, 3], x => x + x)  //  [2, 4, 6]
      
    • Array.of():用于將一組值寻定,轉換為數(shù)組

      Array.of()  //  []
      Array.of(3, 11, 8)  //  [3,11,8]
      Array.of(3)  //  [3]
      Array.of(3).length  //  1
      
      // 這個方法的主要目的,是彌補數(shù)組構造函數(shù)Array()的不足精耐。因為參數(shù)個數(shù)的不同狼速,會導致Array()的行為有差異。
      Array()  //  []
      Array(7)  //  [empty, empty, empty, empty, empty, empty]
      Array(3, 11, 8)  //  [3, 11, 8]
      
    • 數(shù)組實例的 copyWithin()
      在當前數(shù)組內部卦停,將指定位置的成員復制到其他位置(會覆蓋原有成員)向胡,然后返回當前數(shù)組,會修改當前數(shù)組惊完。
      Array.prototype.copyWithin(target, start = 0, end = this.length)
      它接受三個參數(shù)僵芹。這三個參數(shù)都應該是數(shù)值,如果不是小槐,會自動轉為數(shù)值拇派。

      1. target(必需):從該位置開始替換數(shù)據(jù)。
      2. start(可選):從該位置開始讀取數(shù)據(jù)凿跳,默認為0件豌。如果為負值,表示倒數(shù)控嗜。
      3. end(可選):到該位置前停止讀取數(shù)據(jù)茧彤,默認等于數(shù)組長度。如果為負值疆栏,表示倒數(shù)曾掂。
      ['a', 'b', 'c', 'd', 'e'].copyWithin(0, 3, 4)  //  ["d", "b", "c", "d", "e"]
      [1, 2, 3, 4, 5].copyWithin(0, 3)  //  [4, 5, 3, 4, 5]
      [1, 2, 3, 4, 5].copyWithin(0, -2, -1)  //  [4, 2, 3, 4, 5]
      
    • 數(shù)組實例的 find() 和 findIndex()

    • 數(shù)組實例的 fill()fill 方法使用給定值惫谤,填充一個數(shù)組

      ['a', 'b', 'c'].fill(7)  //  [7, 7, 7]
      new Array(3).fill(7)  //  [7, 7, 7]
      // 可以接受第二個和第三個參數(shù),用于指定填充的起始位置和結束位置
      ['a', 'b', 'c'].fill(7, 1, 2)  //  ['a', 7, 'c']
      [1, 2, 3, 4].fill(5, 1)  //  [1, 5, 5, 5]
      
    • 數(shù)組實例的 entries()遭殉,keys() 和 values()

      /*
      * 用于遍歷數(shù)組石挂,都返回一個遍歷器對象,可以用 for...of 循環(huán)進行遍歷
      * 唯一的區(qū)別是 keys() 是對鍵名的遍歷险污、values() 是對鍵值的遍歷痹愚、entries() 是對鍵值對的遍歷
      */
      for (let index of ['a', 'b'].keys()) {
        console.log(index);
      }
      // 0
      // 1
      
      for (let elem of ['a', 'b'].values()) {
        console.log(elem);
      }
      // 'a'
      // 'b'
      
      for (let [index, elem] of ['a', 'b'].entries()) {
        console.log(index, elem);
      }
      // 0 "a"
      // 1 "b"
      
    • 數(shù)組的空位:明確將空位轉為 undefined

ES7(ES2016)

  1. 數(shù)組實例的 includes()
    返回一個布爾值,表示某個數(shù)組是否包含給定的值蛔糯,與字符串的 includes 方法類似

    [1, 2, 3].includes(2);  //  true
    [1, 2, 3].includes(4);  //  false
    [1, 2, NaN].includes(NaN);  //  true
    

    該方法的第二個參數(shù)表示搜索的起始位置拯腮,默認為0。如果第二個參數(shù)為負數(shù)蚁飒,則表示倒數(shù)的位置动壤,如果這時它大于數(shù)組長度(比如第二個參數(shù)為-4,但數(shù)組長度為3)淮逻,則會重置為從0開始琼懊。

    [1, 2, 3].includes(3, 3);  // false
    [1, 2, 3].includes(3, -1); // true
    

    另外,MapSet 數(shù)據(jù)結構有一個 has 方法爬早,需要注意與 includes 區(qū)分哼丈。
    1. Map 結構的has方法,是用來查找鍵名的筛严,比如 Map.prototype.has(key)醉旦、WeakMap.prototype.has(key)、Reflect.has(target, propertyKey)桨啃。
    2. Set 結構的 has 方法车胡,是用來查找值的,比如 Set.prototype.has(value)照瘾、WeakSet.prototype.has(value)匈棘。

  2. 冪運算符 **

    console.log(2**10) // 1024
    console.log(Math.pow(2, 10)) // 1024
    
  3. 模板字符串(Template string)
    ES7 起,帶標簽的模版字面量遵守以下轉義序列的規(guī)則:

    • Unicode 字符以 "\u" 開頭析命,例如 \u00A9
    • Unicode 碼位用"\u{}"表示主卫,例如 \u{2F804}
    • 十六進制以 "\x" 開頭,例如 \xA9
    • 八進制以 "" 和數(shù)字開頭碳却,例如 \251

ES8(ES2017)

  1. async / await
    Promise 的語法糖,專門解決回調地獄笑旺,async 函數(shù)返回一個 Promise 對象昼浦。async 函數(shù)內部 return 語句返回的值,會成為 then 方法回調函數(shù)的參數(shù)筒主。

    async function f() {
      return 'hello world';
    }
    f().then(v => console.log(v))  //  "hello world"
    // 同時觸發(fā)寫法
    let [foo, bar] = await Promise.all([getFoo(), getBar()]);
    
  2. Object.values():返回一個給定對象自身的所有可枚舉屬性值的數(shù)組

    const object1 = {
      a: 'somestring',
      b: 42,
      c: false
    }
    console.log(Object.values(object1)) // ["somestring", 42, false]
    
  3. Object.entries():返回一個給定對象自身可枚舉屬性的鍵值對數(shù)組

    const object1 = {
        a: 'somestring',
        b: 42
    }
    console.log(Object.entries(object1)) // [["a","somestring"],["b",42]]
    for (let [key, value] of Object.entries(object1)) {
          console.log(`${key}: ${value}`)
    }
    // "a: somestring"
    // "b: 42"
    
  4. padStart():用另一個字符串填充當前字符串(重復关噪,如果需要的話)鸟蟹,以便產(chǎn)生的字符串達到給定的長度。填充從當前字符串的開始(左側)應用的使兔。

    const str1 = '5'
    console.log(str1.padStart(4, '0'))  //  "0005"
    // 若無第二個參數(shù)建钥,用空格填充
    console.log(str1.padStart(4))  //  "   5"
    
  5. padEnd():用一個字符串填充當前字符串(如果需要的話則重復填充),返回填充后達到指定長度的字符串虐沥。從當前字符串的末尾(右側)開始填充熊经。

    const str1 = 'Breaded Mushrooms'
    console.log(str1.padEnd(25, '.'))  //  "Breaded Mushrooms........"
    const str2 = '200'
    console.log(str2.padEnd(5))  //  "200  "
    
  6. 函數(shù)參數(shù)結尾逗號

  7. SharedArrayBuffer對象
    SharedArrayBuffer 對象用來表示一個通用的,固定長度的原始二進制數(shù)據(jù)緩沖區(qū)欲险,類似于 ArrayBuffer 對象镐依,它們都可以用來在共享內存(shared memory)上創(chuàng)建視圖。與 ArrayBuffer 不同的是天试,SharedArrayBuffer 不能被分離槐壳。

    // 參數(shù)length指所創(chuàng)建的數(shù)組緩沖區(qū)的大小,以字節(jié)(byte)為單位
    let sab = new SharedArrayBuffer(1024)  // 創(chuàng)建一個1024字節(jié)的緩沖
    
  8. Atomics對象
    Atomics對象 提供了一組靜態(tài)方法用來對 SharedArrayBuffer 對象進行原子操作喜每。

    • Atomics.add():將指定位置上的數(shù)組元素與給定的值相加务唐,并返回相加前該元素的值。
    • Atomics.and():將指定位置上的數(shù)組元素與給定的值相與,并返回與操作前該元素的值哨鸭。
    • Atomics.compareExchange():如果數(shù)組中指定的元素與給定的值相等徒河,則將其更新為新的值,并返回該元素原先的值崇堰。
    • Atomics.exchange():將數(shù)組中指定的元素更新為給定的值,并返回該元素更新前的值涩咖。
    • Atomics.load():返回數(shù)組中指定元素的值海诲。
    • Atomics.or():將指定位置上的數(shù)組元素與給定的值相或,并返回或操作前該元素的值檩互。
    • Atomics.store():將數(shù)組中指定的元素設置為給定的值特幔,并返回該值。
    • Atomics.sub():將指定位置上的數(shù)組元素與給定的值相減闸昨,并返回相減前該元素的值蚯斯。
    • Atomics.xor():將指定位置上的數(shù)組元素與給定的值相異或,并返回異或操作前該元素的值饵较。
    • Atomics.wait():檢測數(shù)組中某個指定位置上的值是否仍然是給定值拍嵌,是則保持掛起直到被喚醒或超時。返回值為 “ok”循诉、“not-equal” 或 “time-out”横辆。調用時,如果當前線程不允許阻塞茄猫,則會拋出異常(大多數(shù)瀏覽器都不允許在主線程中調用 wait())狈蚤。
    • Atomics.wake():喚醒等待隊列中正在數(shù)組指定位置的元素上等待的線程困肩。返回值為成功喚醒的線程數(shù)量。
    • Atomics.isLockFree(size):可以用來檢測當前系統(tǒng)是否支持硬件級的原子操作脆侮。對于指定大小的數(shù)組锌畸,如果當前系統(tǒng)支持硬件級的原子操作,則返回 true靖避;否則就意味著對于該數(shù)組潭枣,Atomics 對象中的各原子操作都只能用鎖來實現(xiàn)。此函數(shù)面向的是技術專家筋蓖。
  9. Object.getOwnPropertyDescriptors():用來獲取一個對象的所有自身屬性的描述符

    const obj = {
      foo: 123,
      get bar() { return 'abc' }
    };
    
    Object.getOwnPropertyDescriptors(obj)
    // { foo:
    //    { value: 123,
    //      writable: true,
    //      enumerable: true,
    //      configurable: true },
    //   bar:
    //    { get: [Function: bar],
    //      set: undefined,
    //      enumerable: true,
    //      configurable: true } }
    
    • 淺拷貝一個對象
      Object.assign() 方法只能拷貝源對象的可枚舉的自身屬性卸耘,同時拷貝時無法拷貝屬性的特性們,而且訪問器屬性會被轉換成數(shù)據(jù)屬性粘咖,也無法拷貝源對象的原型蚣抗,該方法配合 Object.create() 方法可以實現(xiàn)上面說的這些。

      Object.create(
        Object.getPrototypeOf(obj),
        Object.getOwnPropertyDescriptors(obj)
       );
      
    • 創(chuàng)建子類
      創(chuàng)建子類的典型方法是定義子類翰铡,將其原型設置為超類的實例漠秋,然后在該實例上定義屬性求晶。這么寫很不優(yōu)雅,特別是對于 getters 和 setter 而言。 相反,您可以使用此代碼設置原型:

      function superclass() {}
      superclass.prototype = {
        // 在這里定義方法和屬性
      };
      function subclass() {}
      subclass.prototype = Object.create(superclass.prototype, Object.getOwnPropertyDescriptors({
        // 在這里定義方法和屬性
      }));
      

ES9(ES2018)

  1. for await…of
    for await...of 語句創(chuàng)建一個循環(huán),該循環(huán)遍歷異步可迭代對象以及同步可迭代對象,包括: 內置的 String, Array,類似數(shù)組對象 (例如 argumentsNodeList)苞尝,TypedArray, Map, Set 和用戶定義的異步/同步迭代器恬涧。其會調用自定義迭代鉤子注益,并為每個不同屬性的值執(zhí)行語句。

    async function* asyncGenerator() {
      var i = 0
      while (i < 3) {
            yield i++
      }
    }
    
    (async function() {
      for await (num of asyncGenerator()) {
            console.log(num)
      }
    })()
    // 0
    // 1
    // 2
    
  2. 模板字符串(Template string)
    ES9 開始溯捆,模板字符串允許嵌套支持常見轉義序列丑搔,移除對 ECMAScript 在帶標簽的模版字符串中轉義序列的語法限制。

  3. 正則表達式 Unicode 轉義
    正則表達式中的 Unicode 轉義符允許根據(jù) Unicode 字符屬性匹配 Unicode 字符提揍。 它允許區(qū)分字符類型低匙,例如大寫和小寫字母,數(shù)學符號和標點符號碳锈。

    // 匹配所有數(shù)字
    const regex = /^\p{Number}+$/u;
    regex.test('231???') // true
    regex.test('???') // true
    regex.test('ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ') // true
    
    // 匹配所有空格
    \p{White_Space}
    
    // 匹配各種文字的所有字母顽冶,等同于 Unicode 版的 \w
    [\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}]
    
    // 匹配各種文字的所有非字母的字符,等同于 Unicode 版的 \W
    [^\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}]
    
    // 匹配 Emoji
    /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu
    
    // 匹配所有的箭頭字符
    const regexArrows = /^\p{Block=Arrows}+$/u;
    regexArrows.test('←↑→↓?????????????') // true
    
  4. 正則表達式 s/dotAll 模式
    JS 正則增加了一個新的標志 s 用來表示 dotAll售碳,這可以匹配任意字符强重。

    const re = /foo.bar/s;  //  等價于 const re = new RegExp('foo.bar', 's');
    re.test('foo\nbar');    // true
    re.dotAll;      // true
    re.flags;       // "s"
    
  5. 具名組匹配

const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;

const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31
  1. 對象擴展操作符

  2. Promise.prototype.finally()
    finally() 方法會返回一個 Promise,當 promise 的狀態(tài)變更间景,不管是變成 rejected 或者 fulfilled,最終都會執(zhí)行 finally() 的回調封拧。

fetch(url)
    .then((res) => {
      console.log(res)
    })
    .catch((error) => { 
      console.log(error)
    })
    .finally(() => { 
      console.log('結束')
  })

ES10(ES2019)

  1. 數(shù)組實例的 flat()
    用于將嵌套的數(shù)組“拉平”,變成一維的數(shù)組捧杉。該方法返回一個新數(shù)組评甜,對原數(shù)據(jù)沒有影響蜕着。參數(shù) depth 表示要提取嵌套數(shù)組的結構深度蓖乘,默認值為 1零聚。
console.log([1 ,[2, 3]].flat());  //  [1, 2, 3]

// 指定轉換的嵌套層數(shù)
console.log([1, [2, [3, [4, 5]]]].flat(2));  //  [1, 2, 3, [4, 5]]

// 不管嵌套多少層【使用 Infinity 作為深度,展開任意深度的嵌套數(shù)組】
console.log([1, [2, [3, [4, 5]]]].flat(Infinity));  //  [1, 2, 3, 4, 5]

// 自動跳過空位【會移除數(shù)組中的空項】
console.log([1, [2, , 3]].flat());  //  [1, 2, 3]

// 傳入 <=0 的整數(shù)將返回原數(shù)組蚂会,不“拉平”
console.log([1, [2, [3, [4, 5]]]].flat(0));  //  [1, [2, [3, [4, 5]]]]
console.log([1, [2, [3, [4, 5]]]].flat(-10));  //  [1, [2, [3, [4, 5]]]]
  1. 數(shù)組實例的 flatMap()
    首先使用映射函數(shù)映射每個元素,然后將結果壓縮成一個新數(shù)組。它與 map 和連著深度值為1的 flat 幾乎相同余指,但 flatMap 通常在合并成一種方法的效率稍微高一些。
[1, 2, 3, 4].flatMap(x => x * 2);  //  [2, 4, 6, 8]
[1, 2, 3, 4].flatMap(x => [x * 2]);  //  [2, 4, 6, 8]

[1, 2, 3, 4].flatMap(x => [[x * 2]]);  //  [[2], [4], [6], [8]]
[1, 2, 3, 4].map(x => [x * 2]);  //  [[2], [4], [6], [8]]
  1. 字符串實例的 trimStart() / trimLeft() / trimEnd() / trimRight()
    去除字符首或尾的空格,trimStart()trimEnd() 才是標準方法足丢,trimLeft()trimRight() 只是別名

  2. Object.fromEntries()
    把鍵值對列表轉換為一個對象斩跌,它是 Object.entries() 的反函數(shù)。

const entries = new Map([
  ['foo', 'bar'],
  ['baz', 42]
])
console.log(Object.fromEntries(entries))  //  Object { foo: "bar", baz: 42 }
  1. Symbol.prototype.description
    通過工廠函數(shù) Symbol() 創(chuàng)建符號時,您可以選擇通過參數(shù)提供字符串作為描述:
Symbol('desc').toString();  //  "Symbol(desc)"
Symbol('desc').description;  //  "desc"
Symbol('').description;  //  ""
Symbol().description;  //  undefined

//全局 symbols
Symbol.for('foo').toString();  //  "Symbol(foo)"
Symbol.for('foo').description;  //  "foo"
  1. Function.prototype.toString()
    現(xiàn)在返回精確字符洛姑,包括空格和注釋

  2. try-catch
    catch 的參數(shù)可省略

ES11(ES2020)

  1. String.prototype.matchAll
    返回一個包含所有匹配正則表達式及分組捕獲結果的迭代器。
var regexp = /t(e)(st(\d?))/g
var str = 'test1test2'

str.match(regexp)  //  ['test1', 'test2']
str.matchAll(regexp)  //  RegExpStringIterator {}
[...str.matchAll(regexp)]  //  [ ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4], ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4] ]
  1. 動態(tài) import()
const modelpath = '/demo'
import(`@/pages${modelpath}`).then(module => {}).catch(err => {})
  1. import.meta
    import.meta 會返回一個對象,有一個 url 屬性两入,返回當前模塊的 url 路徑,只能在模塊內部使用。

  2. export * as XX from 'module'import * as XX from 'module'

  3. Promise.allSettled()
    Promise.allSettled 方法返回一個在所有給定的 promise 都已經(jīng) fulfilledrejected 后的 promise 她我,并帶有一個對象數(shù)組矾踱,每個對象表示對應的 promise 結果呛讲。

  4. BigInt
    現(xiàn)在的基本數(shù)據(jù)類型(值類型)不止5種(ES6之后是六種)了哦芽偏!加上 BigInt 一共有七種基本數(shù)據(jù)類型,分別是: String、Number、Boolean、Null、Undefined、Symbol、BigInt
    BigInt 可以表示任意大的整數(shù)堆缘÷槌担可以用在一個整數(shù)字面量后面加 n 的方式定義一個 BigInt ,如:10n免钻,或者調用函數(shù) BigInt()握童。

  5. globalThis
    指向全局對象稽揭,瀏覽器下指向 window

  6. 可選鏈操作符(?.)
    info.animal?.reptile?.tortoise

  7. 空值合并操作符(??)
    當左側的操作數(shù)為 null 或者 undefined 時步鉴,返回其右側操作數(shù)阳似,否則返回左側操作數(shù)。
    與邏輯或操作符(||)不同,邏輯或操作符會在左側操作數(shù)為假值時返回右側操作數(shù)青自。

const foo = null ?? 'default string';
console.log(foo);  // "default string"

const baz = 0 ?? 42;
console.log(baz);  // 0

ES12(ES2021)(預計將在2021年年中發(fā)布)

  1. String.prototype.replaceAll
    replaceAll 返回一個全新的字符串伙单,所有符合匹配規(guī)則的字符都將被替換掉吻育,替換規(guī)則可以是字符串或者正則表達式。
let string = 'I like 前端,I like 前端公蝦米'
console.log(string.replace(/like/g,'love'))  // 'I love 前端,I love 前端公蝦米'
console.log(string.replaceAll('like','love'))  // 'I love 前端,I love 前端公蝦米'

需要注意的是淤井,replaceAll 在使用正則表達式的時候布疼,如果非全局匹配(/g),則 replaceAll() 會拋出一個異常

console.log(string.replaceAll(/like/,'love'))  // TypeError
  1. Promise.any
    Promise 列表中的任意一個 promise 成功 resolve 則返回第一個 resolve 的結果狀態(tài)币狠,如果所有的 promisereject游两,則拋出異常表示所有請求失敗。
    Promise.race 一旦某個 promise 觸發(fā)了 resolve 或者 reject漩绵,就直接返回了該狀態(tài)結果贱案,并不在乎其成功或者失敗。

  2. WeakRefs
    當我們通過(const止吐、let宝踪、var)創(chuàng)建一個變量時,垃圾收集器 GC 將永遠不會從內存中刪除該變量碍扔,只要它的引用仍然存在可訪問瘩燥。WeakRef 對象包含對對象的弱引用。對對象的弱引用是不會阻止垃圾收集器 GC 恢復該對象的引用蕴忆,則 GC 可以在任何時候刪除它颤芬。
    WeakRefs 在很多情況下都很有用悲幅,比如使用 Map 對象來實現(xiàn)具有很多需要大量內存的鍵值緩存套鹅,在這種情況下最方便的就是盡快釋放鍵值對占用的內存。
    目前汰具,可以通過 WeakMap() 或者 WeakSet() 來使用 WeakRefs卓鹿。

  3. 邏輯運算符和賦值表達式
    表達式 a op= b 等同于 a = a op (a = b)

a ||= b
//等價于
a = a || (a = b)  // 當LHS值不存在時,將RHS變量賦值給LHS

a &&= b
//等價于
a = a && (a = b)  // 當LHS值存在時留荔,將RHS變量賦值給LHS

a ??= b
//等價于
a = a ?? (a = b)  // 當LHS值為null或者undefined時吟孙,將RHS變量賦值給LHS
  1. 數(shù)字分隔符號
    數(shù)字分隔符,可以在數(shù)字之間創(chuàng)建可視化分隔符聚蝶,通過 _ 下劃線來分割數(shù)字杰妓,使數(shù)字更具可讀性
const money = 1_000_000_000
//等價于
const money = 1000000000

const totalFee = 1000.12_34
//等價于
const totalFee = 1000.1234

// 該新特性同樣支持在八進制數(shù)中使用
const number = 0o123_456
//等價于
const number = 0o123456
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市碘勉,隨后出現(xiàn)的幾起案子巷挥,更是在濱河造成了極大的恐慌,老刑警劉巖验靡,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件倍宾,死亡現(xiàn)場離奇詭異雏节,居然都是意外死亡,警方通過查閱死者的電腦和手機高职,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門钩乍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人怔锌,你說我怎么就攤上這事寥粹。” “怎么了产禾?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵排作,是天一觀的道長。 經(jīng)常有香客問我亚情,道長妄痪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任楞件,我火速辦了婚禮衫生,結果婚禮上,老公的妹妹穿的比我還像新娘土浸。我一直安慰自己罪针,他們只是感情好,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布黄伊。 她就那樣靜靜地躺著泪酱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪还最。 梳的紋絲不亂的頭發(fā)上墓阀,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機與錄音拓轻,去河邊找鬼斯撮。 笑死,一個胖子當著我的面吹牛扶叉,可吹牛的內容都是我干的勿锅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼枣氧,長吁一口氣:“原來是場噩夢啊……” “哼溢十!你這毒婦竟也來了?” 一聲冷哼從身側響起达吞,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤张弛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乌庶,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡种蝶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瞒大。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片螃征。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖透敌,靈堂內的尸體忽然破棺而出盯滚,到底是詐尸還是另有隱情,我是刑警寧澤酗电,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布魄藕,位于F島的核電站,受9級特大地震影響撵术,放射性物質發(fā)生泄漏背率。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一嫩与、第九天 我趴在偏房一處隱蔽的房頂上張望寝姿。 院中可真熱鬧,春花似錦划滋、人聲如沸饵筑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽根资。三九已至,卻和暖如春同窘,著一層夾襖步出監(jiān)牢的瞬間玄帕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工塞椎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留桨仿,地道東北人睛低。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓案狠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親钱雷。 傳聞我的和親對象是個殘疾皇子骂铁,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內容