javaScript ES7 ES8 ES9 ES10新特性


參考文獻: https://tuobaye.com/2018/11/27/%E7%BB%86%E8%A7%A3JavaScript-ES7-ES8-ES9-%E6%96%B0%E7%89%B9%E6%80%A7/

http://www.imooc.com/article/291875

https://hijiangtao.github.io/2019/07/05/Diff-ECMAScript-2019/

ES7

1. Array.prototype.includes()方法

['a', 'b', 'c', 'd'].includes('b')         // true
['a', 'b', 'c', 'd'].includes('b', 1)      // true
['a', 'b', 'c', 'd'].includes('b', 2)      // false
var ary1 = [NaN];
console.log(ary1.indexOf(NaN))//-1
console.log(ary1.includes(NaN))//true

2. 求冪運算符(**)

**來替代Math.pow。

4 ** 3

等價於

Math.pow(4,3)
let n = 4;
n **= 3;

ES8

1. Async Functions

Async Functions也就是我們常說的Async/Await。Async/Await是一種用於處理JS異步操作的語法糖,可以幫助我們擺脫回調地獄,編寫更加優雅的代碼。

通俗的理解,async關鍵字的作用是告訴編譯器對於標定的函數要區別對待。當編譯器遇到標定的函數中的await關鍵字時,要暫時停止運行,帶到await標定的函數處理完畢后,再進行相應操作。如果該函數fulfilled了,則返回值是resolve value,否則得到的就是reject value。

拿普通的promise寫法來對比:

async function asyncFunc() {
    const result = await otherAsyncFunc();
    console.log(result);
}

// Equivalent to:
function asyncFunc() {
    return otherAsyncFunc()
    .then(result => {
        console.log(result);
    });
}

並行處理多個函數:

async function asyncFunc() {
    const [result1, result2] = await Promise.all([
        otherAsyncFunc1(),
        otherAsyncFunc2(),
    ]);
    console.log(result1, result2);
}

// Equivalent to:
function asyncFunc() {
    return Promise.all([
        otherAsyncFunc1(),
        otherAsyncFunc2(),
    ])
    .then([result1, result2] => {
        console.log(result1, result2);
    });
}

處理錯誤:

async function asyncFunc() {
    try {
        await otherAsyncFunc();
    } catch (err) {
        console.error(err);
    }
}

// Equivalent to:
function asyncFunc() {
    return otherAsyncFunc()
    .catch(err => {
        console.error(err);
    });
}

2. SharedArrayBuffer和Atomics

SharedArrayBuffer允許在多個 workers 和主線程之間共享 SharedArrayBuffer 對象的字節。這種共享有兩個好處:

  • 可以更快地在 workers 之間共享數據。
  • workers 之間的協調變得更簡單和更快(與 postMessage() 相比)

API:

  構造函數: new SharedArrayBuffer(length)

  靜態屬性: SharedArrayBuffer[Symbol.species]

  實例屬性: SharedArrayBuffer.prototype.byteLength()

              SharedArrayBuffer.prototype.slice(start, end)

Atomics 方法可以用來與其他 workers 進行同步。以下兩個操作可以讓你讀取和寫入數據,並且不會被編譯器重新排列:

  • Atomics.load(ta : TypedArray, index)
  • Atomics.store(ta : TypedArray, index, value : T)

這個想法是使用常規操作讀取和寫入大多數數據,而 Atomics 操作(load ,store 和其他操作)可確保讀取和寫入安全。通常,要使用自定義同步機制(例如)可以基於Atomics實現

API: 

Atomic 函數的主要操作數必須是 Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array 或 Uint32Array 的一個實例。它必須包裹一個 SharedArrayBuffer.

    • Atomics.load(ta : TypedArray, index) : T
      讀取和返回 ta[index] 上的元素,返回數組指定位置上的值。
    • Atomics.store(ta : TypedArray, index, value : T) : T
      在 ta[index] 上寫入 value,並且返回 value。
    • Atomics.exchange(ta : TypedArray, index, value : T) : T
      將 ta[index] 上的元素設置為 value ,並且返回索引 index 原先的值。
    • Atomics.compareExchange(ta : TypedArray, index, expectedValue, replacementValue) : T
      如果 ta[index] 上的當前元素為 expectedValue , 那么使用 replacementValue 替換。並且返回索引 index 原先(或者未改變)的值。
    • Atomics.add(ta : TypedArray, index, value) : T
      執行 ta[index] += value 並返回 ta[index] 的原始值。
    • Atomics.sub(ta : TypedArray, index, value) : T
      執行 ta[index] -= value 並返回 ta[index] 的原始值。
    • Atomics.and(ta : TypedArray, index, value) : T
      執行 ta[index] &= value 並返回 ta[index] 的原始值。
    • Atomics.or(ta : TypedArray, index, value) : T
      執行 ta[index] |= value 並返回 ta[index] 的原始值。
    • Atomics.xor(ta : TypedArray, index, value) : T
      執行 ta[index] ^= value 並返回 ta[index] 的原始值。
    • Atomics.wait(ta: Int32Array, index, value, timeout=Number.POSITIVE_INFINITY) : (‘not-equal’ | ‘ok’ | ‘timed-out’)
      如果 ta[index] 的當前值不是 value ,則返回 ‘not-equal’。否則(等於value時)繼續等待,直到我們通過 Atomics.wake() 喚醒或直到等待超時。 在前一種情況下,返回 ‘ok’。在后一種情況下,返回’timed-out’。timeout 以毫秒為單位。記住此函數執行的操作:“如果 ta[index] 為 value,那么繼續等待” 。
    • Atomics.wake(ta : Int32Array, index, count)
      喚醒等待在 ta[index] 上的 count workers。

3. Object.values and Object.entries

const obj = { 10: 'xxx', 1: 'yyy', 3: 'zzz' };
Object.values(obj); // ['yyy', 'zzz', 'xxx']

Object.values('es8'); // ['e', 's', '8']
const obj = ['e', 's', '8'];
Object.entries(obj); // [['0', 'e'], ['1', 's'], ['2', '8']]

const obj = { 10: 'xxx', 1: 'yyy', 3: 'zzz' };
Object.entries(obj); // [['1', 'yyy'], ['3', 'zzz'], ['10': 'xxx']]

Object.entries('es8'); // [['0', 'e'], ['1', 's'], ['2', '8']]

4. String padding

為 String 對象增加了 2 個函數:padStart 和 padEnd。填補字符串的首部和尾部,為了使得到的結果字符串的長度能達到給定的長度(targetLength)。你可以通過特定的字符,或者字符串,或者默認的空格填充它。

str.padStart(targetLength [, padString])
str.padEnd(targetLength [, padString])

'es8'.padStart(2);          // 'es8'
'es8'.padStart(5);          // '  es8'
'es8'.padStart(6, 'woof');  // 'wooes8'
'es8'.padStart(14, 'wow');  // 'wowwowwowwoes8'
'es8'.padStart(7, '0');     // '0000es8'

'es8'.padEnd(2);            // 'es8'
'es8'.padEnd(5);            // 'es8  '
'es8'.padEnd(6, 'woof');    // 'es8woo'
'es8'.padEnd(14, 'wow');    // 'es8wowwowwowwo'
'es8'.padEnd(7, '6');       // 'es86666'

5. Object.getOwnPropertyDescriptors

const obj = { 
  get es7() { return 777; },
  get es8() { return 888; }
};
Object.getOwnPropertyDescriptor(obj);
// {
//   es7: {
//     configurable: true,
//     enumerable: true,
//     get: function es7(){}, //the getter function
//     set: undefined
//   },
//   es8: {
//     configurable: true,
//     enumerable: true,
//     get: function es8(){}, //the getter function
//     set: undefined
//   }
// }

6. 結尾逗號

// 參數定義時
function foo(
    param1,
    param2,
) {}

// 函數調用時
foo(
    'abc',
    'def',
);

// 對象中
let obj = {
    first: 'Jane',
    last: 'Doe',
};

// 數組中
let arr = [
    'red',
    'green',
    'blue',
];

ES9新特性

1.異步迭代器:異步迭代器對象的next()方法返回了一個Promise,解析后的值跟普通的迭代器類似。

async function example() {
  // 普通迭代器:
  const iterator = createNumberIterator();
  iterator.next(); // Object {value: 1, done: false}
  iterator.next(); // Object {value: 2, done: false}
  iterator.next(); // Object {value: 3, done: false}
  iterator.next(); // Object {value: undefined, done: true}

  // 異步迭代器:
  const asyncIterator = createAsyncNumberIterator();
  const p = asyncIterator.next(); // Promise
  await p;// Object {value: 1, done: false}
  await asyncIterator.next(); // Object {value: 2, done: false}
  await asyncIterator.next(); // Object {value: 3, done: false}
  await asyncIterator.next(); // Object {value: undefined, done: true}
}

2.  Rest/Spread 屬性

rest參數和展開運算符,這項特性在ES6中已經引入,但是ES6中僅限於數組。在ES9中,為對象提供了像數組一樣的rest參數和擴展運算符。
const obj = {
  a: 1,
  b: 2,
  c: 3
}
const { a, ...param } = obj;
  console.log(a)     //1
  console.log(param) //{b: 2, c: 3}

function foo({a, ...param}) {
  console.log(a);    //1
  console.log(param) //{b: 2, c: 3}
}

3.  Promise.prototype.finally()

finally的回調總會被執行。

promise
  .then(result => {···})
  .catch(error => {···})
  .finally(() => {···});

4. 命名捕獲組

ES9中可以通過名稱來識別捕獲組:

(?<year>[0-9]{4})

before:

const RE_DATE = /([0-9]{4})-([0-9]{2})-([0-9]{2})/;

const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj[1]; // 1999
const month = matchObj[2]; // 12
const day = matchObj[3]; // 31

after:

const RE_DATE = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<date>[0-9]{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.date; // 31

// 使用解構語法更為簡便
const {groups: {day, year}} = RE_DATE.exec('1999-12-31');
console.log(year); // 1999
console.log(day); // 31

 

 ES10新特性

1. 選擇性的catch綁定

在使用try catch錯誤異常處理時,可以選擇性的給catch傳入參數(可以不給catch傳參)

正常使用try catch:

 

try {
    // do something
} catch (err) {
    // console.log('err', err);
}

 

在es10中使用時,可以:

try {
    // do something
} catch {
    // do something
}

2. JSON.superset

背景: JSON內容可以正常包含 行分隔符(\u2028)段落分隔符(\u2029而ECMAScript卻不行。

在ES10中,可以直接使用

eval('\u2029');

 

而不會在提示錯誤。

3. Symbol.prototype.description

為Symbol類型增加Symbol.prototype.description的一個訪問器屬性,用來獲取Symbol類型數據的描述信息。

 

console.log(Symbol('test').description);
// 'test'

console.log(Symbol.for('test').description);
// 'test'

console.log(Symbol.iterator.description);
// 'Symbol.iterator'

 

4. Function.prototype.toString

在ES10之后,函數調用toString()方法,將准確返回原有信息,包括空格和注釋等。

 

let funcToString = function () {
    //do something
    console.log('test');
}
/**
"function () {
    //do something
    console.log('test');
}"
*/

 

5. Object.fromEntries()

Object.fromEntries()Object.entries()的反轉。

 

const obj = { foo: 'bar', baz: 42}
let res1 = Object.entries(obj);
console.log(res1);
// [['foo', 'bar'], ['baz', 42]]
let obj1= Object.fromEntries(res1);
console.log(obj1);
// {foo: 'bar', baz: 42}

 

map轉換為object

let map = new Map([['name','alex'], ['age', 18]]);
const obj2 = Object.fromEntries(map);
console.log(obj2);
// object {name: 'alex', age: 18}

6. 更友好的JSON.stringify

正常字符的表示不變:

 

JSON.stringify('𝌆')
// → '"𝌆"'
JSON.stringify('\uD834\uDF06')
// → '"𝌆"'

 

而無法用 UTF-8 編碼表示的字符會被序列化為轉移序列:

JSON.stringify('\uDF06\uD834')
// → '"\\udf06\\ud834"'
JSON.stringify('\uDEAD')
// → '"\\udead"'

7. String.prototype.{trimStart, trimEnd}

trimStart()從字符串開頭刪除空格,返回一個新的字符串,不會修改原字符串。

 

let str = '        hello, miss cecelia!';
console.log(str.trimStart());
// 'hello, miss cecelia!'

 

trimEnd()從字符串右端開始移除空白字符,返回一個新的字符串,不會修改原字符串。

 

let str = '        hello, miss cecelia!             ';
console.log(str.trimEnd());
// '        hello, miss cecelia!'

 

8. Array.prototype.{flat, flatMap}

Array.prototype.flat()可顯式地傳入參數,表示打平的層級。不傳參數,表示只打平第一級。

 

let arr = [1,2,3,[1,2,[3,[4]]]];
console.log(arr.flat());
// [1,2,3,1,2,[3,[4]]]
console.log(arr.flat(2));
// [1,2,3,1,2,3,[4]]

 

flatMap()方法:可以看作flat和map組合在一起的結果:

 

['My dog', 'is awesome'].map(words => words.split(' '))
// [ [ 'My', 'dog' ], [ 'is', 'awesome' ] ]
['My dog', 'is awesome'].flatMap(words => words.split(' '))
//[ 'My', 'dog', 'is', 'awesome' ]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM