[譯] 是的,ES2017 (ES8)來了

CcCooL0807發表於2019-03-04

本文主要講解 ES8 ( ES2017 )新增的功能、特性

ES8 或者說是 ES2017 已經在今年6月底的時候被 TC39 正式釋出。似乎我們在最近的一年裡就已經談論了很多有關 ECMA 的事情。現在的 ES 標準每年釋出一次。我們都知道 ES6 是在2015年釋出的,ES7 是在2016年釋出的,但是估計會有很少數人知道 ES5 是在何時釋出的。答案是2009年,是在 JavaScript 逐漸變的流行之前釋出的。

JavaScript,作為一門處於高速發展期的開發語言,正在變的越來越完善、穩定。我們必須擁抱這些變化,並且我們需要把ES8加入到我們的技術棧中。

如果您想對 ES8 做一個深入、徹底的瞭解,您可以查閱Web 資源或者PDF 資源。其他的讀者,您可以直接查閱本文,因為本文將涵蓋 ES8 主要的新特性,並且會附上程式碼示例。


字串填充

在 String 物件中,ES8 增加了兩個新的函式: padStart 和 padEnd 。正如其名,這倆函式的作用就是在字串的頭部和尾部增加新的字串,並且返回一個具有指定長度的新的字串。你可以使用指定的字元、字串或者使用函式提供的預設值-空格來填充源字串。具體的函式申明如下:

str.padStart(targetLength [, padString])

str.padEnd(targetLength [, padString])複製程式碼

正如你所看到的,這倆函式的第一個引數(必輸)是 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`複製程式碼

目前瀏覽器的支援情況如下(資訊來自 MDN ):

[譯] 是的,ES2017 (ES8)來了


values和entries函式

在 Object 中,ES8 也新增了兩個新的函式,分別是 Object.values 函式和 Object.entries 函式。Object.values 函式將會返回一個陣列,該陣列的內容是函式引數(一個物件)可遍歷屬性的屬性值。陣列中得到的屬性值的順序與你在對引數物件使用 for in 語句時獲取到的屬性值的順序一致。函式宣告如下:

Object.values(obj)複製程式碼

引數 obj 就是源物件,它可以是一個物件或者一個陣列(因為陣列可以看作是陣列下標為 key ,陣列元素為 value 的特殊物件)。具體的程式碼示例如下:

const obj = { x: `xxx`, y: 1 };
Object.values(obj); // [`xxx`, 1]

const obj = [`e`, `s`, `8`]; // same as { 0: `e`, 1: `s`, 2: `8` };
Object.values(obj); // [`e`, `s`, `8`]

// when we use numeric keys, the values returned in a numerical 
// order according to the keys
const obj = { 10: `xxx`, 1: `yyy`, 3: `zzz` };
Object.values(obj); // [`yyy`, `zzz`, `xxx`]
Object.values(`es8`); // [`e`, `s`, `8`]複製程式碼

目前瀏覽器對於 Object.values 函式的支援情況如下(資訊來自 MDN ):

[譯] 是的,ES2017 (ES8)來了

介紹完 Object.values 函式,接下來繼續介紹 Object.entries 函式。 Object.entries 函式與 Object.values 函式類似,也是返回一個陣列,只不過這個陣列是一個以源物件(引數)的可列舉屬性的鍵值對為陣列 [key, value] 的 n 行 2 列的陣列。它的返回順序與 Object.values 函式類似。它的函式宣告如下:

Object.entries(obj)複製程式碼

示例程式碼如下:

const obj = { x: `xxx`, y: 1 };
Object.entries(obj); // [[`x`, `xxx`], [`y`, 1]]

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`]]複製程式碼

目前瀏覽器對於 Object.entries 函式的支援情況如下(資訊來自 MDN ):

[譯] 是的,ES2017 (ES8)來了


getOwnPropertyDescriptors函式

Object 中還有一個新成員,那就是 Object.getOwnPropertyDescriptors 函式。該函式返回指定物件(引數)的所有自身屬性描述符。所謂自身屬性描述符就是在物件自身內定義,不是通過原型鏈繼承來的屬性。函式宣告如下:

Object.getOwnPropertyDescriptors(obj)複製程式碼

obj 引數即為源物件,該函式返回的每個描述符物件可能會有的 key 值分別是:configurableenumerablewritablegetsetvalue。示例程式碼如下:

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
//   }
// }複製程式碼

描述符資料非常重要,尤其是在裝飾器上。該函式的瀏覽器支援情況如下(資訊來自 MDN ):

[譯] 是的,ES2017 (ES8)來了


結尾逗號

此處結尾逗號指的是在函式引數列表中最後一個引數之後的逗號以及函式呼叫時最後一個引數之後的逗號。ES8 允許在函式定義或者函式呼叫時,最後一個引數之後存在一個結尾逗號而不報 SyntaxError 的錯誤。示例程式碼如下:

函式宣告時

function es8(var1, var2, var3,) {
  // ...
}複製程式碼

函式呼叫時

es8(10, 20, 30,);複製程式碼

ES8的這項新特性受啟發於物件或者陣列中最後一項內容之後的逗號,如 [10, 20, 30,]{ x: 1, }


非同步函式

async 關鍵字定義的函式宣告定義了一個可以非同步執行的函式,它返回一個 AsyncFunction 型別的物件。非同步函式的內在執行機制和 Generator 函式非常類似,但是不能轉化為 Generator 函式。

ps: 不理解 Generator 函式的讀者可以參考阮一峰大師的ES6入門中關於Generator函式的講解

示例程式碼如下:

function fetchTextByPromise() {
  return new Promise(resolve => { 
    setTimeout(() => { 
      resolve("es8");
    }, 2000);
  });
}
async function sayHello() { 
  const externalFetchedText = await fetchTextByPromise();
  console.log(`Hello, ${externalFetchedText}`); // Hello, es8
}
sayHello();複製程式碼

上述程式碼中, sayHello 函式的呼叫將會導致在2秒之後列印 Hello, es8 。繼續來看一段程式碼:

console.log(1);
sayHello();
console.log(2);複製程式碼

輸出將會變成:

1 // immediately
2 // immediately
Hello, es8 // after 2 seconds複製程式碼

之所以會列印上述內容,那是因為非同步函式不會阻塞程式的繼續執行。

譯者注:

此處打個小廣告,如果有讀者對於 JavaScript 的非同步機制還有不明白的地方,可以參考本人的一篇部落格javascript非同步機制,裡面是本人關於非同步機制的一點拙見,相信會對您有一點啟發。歡迎指正與交流!

非同步函式的瀏覽器支援情況如下(資訊來自 MDN ):

[譯] 是的,ES2017 (ES8)來了


共享記憶體與原子操作

當記憶體被共享時,多個執行緒可以併發讀、寫記憶體中相同的資料。原子操作可以確保那些被讀、寫的值都是可預期的,即新的事務是在舊的事務結束之後啟動的,舊的事務在結束之前並不會被中斷。這部分主要介紹了 ES8 中新的建構函式 SharedArrayBuffer 以及擁有許多靜態方法的名稱空間物件 Atomic

Atomic 物件類似於 Math 物件,擁有許多靜態方法,所以我們不能把它當做建構函式。 Atomic 物件有如下常用的靜態方法:

  • add /sub – 為某個指定的value值在某個特定的位置增加或者減去某個值
  • and / or /xor – 進行位操作
  • load – 獲取特定位置的值

該部分的瀏覽器相容情況如下(資訊來自 MDN ):

[譯] 是的,ES2017 (ES8)來了


取消模版字串限制( ES9 )

使用 ES6 中規定的模版字串,我們可以做如下事情:

const esth = 8;
helper`ES ${esth} is `;
function helper(strs, ...keys) {
  const str1 = strs[0]; // ES
  const str2 = strs[1]; // is
  let additionalPart = ``;
  if (keys[0] == 8) { // 8
    additionalPart = `awesome`;
  }
  else {
    additionalPart = `good`;
  }

  return `${str1} ${keys[0]} ${str2} ${additionalPart}.`;
}複製程式碼

上述程式碼的返回值將會是 ES 8 is awesome 。如果 esth 是 7 的話,那麼返回值將會是 ES 7 is good 。這樣做完全沒有問題,很酷!但是我們在使用模版字串的時候,有一個限制,那就是不能使用類似於 u 或者 x 的子字串, ES9 正在處理這個問題。詳情請查閱MDN或者TC39文件模板字串修正(非模板字串)的瀏覽器相容情況如下(資訊來自 MDN ):

[譯] 是的,ES2017 (ES8)來了


結語

JavaScript 正處於高速發展中,時常會被更新。我們必須準備好接受、擁抱 JavaScript 的新特性。最後,上述這些特性被 TC39 委員會所確認以及被一些核心開發人員所實現。甚至許多新特性現在已經成為了 TypeScript、瀏覽器以及一些語法糖的一部分,所以我們現在就可以嘗試使用它們,積極擁抱新特性。

最後,你可以在Medium或者Twitter上來關注我,進而檢視更多有關 JavaScript 和 Angular 的文章。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃

相關文章