ES2018 新增特性清單

antwang發表於2019-03-01

Rest/Spread 屬性

rest

將物件的剩餘屬性複製到一個新物件中。

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }
複製程式碼

spread

將物件的屬性快速複製到另一個物件。

let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }
複製程式碼

非同步iterator和非同步iterables

與iterator不同,非同步iterator的next()方法返回一個包含{ value, done }的promise。

const { value, done } = syncIterator.next();

asyncIterator.next().then(({ value, done }) => /* ... */);
複製程式碼

可以看到syncIterator是一個非同步遍歷器。它可以通過非同步generator生成。下面演示如何定義非同步generator函式。

非同步 generator 函式


async function* asyncGen() {
  let p1 = new Promise((resolve, reject) =>{
      setTimeout(()=>{
          resolve(1);
      }, 1000)
  });
  let p2 = new Promise((resolve, reject) =>{
      setTimeout(()=>{
          resolve(2);
      }, 1000)
  });
  yield await p1;
  yield await p2
}
複製程式碼

for-await-of

es2018提供了新的遍歷語法對非同步 iterator 進行遍歷。

for await (const val of asyncGen()) {
  console.log(val);
}
複製程式碼

Promise.prototype.finally()

Promise.prototype.finally()不管promise的執行結果是成功還是失敗,在promise執行完成後,會觸發一個回撥函式。常見的應用場景比如在ajax請求成功或失敗後,隱藏loading動畫。

fetch(`https://demo.com/endpoint`)
.then(res => {
    // ...
})
.catch(err => {
    // ...
})
.finally(() => {
    // do sth no matter success or failure
})
複製程式碼

tagged 模板字串與 轉義序列

從es2016開始,tagged 模板字串會對以u、u{}、x開頭或者加數字開頭的字串進行轉義。但是如果在模板字串中出現以上述字元開頭的非轉義字元的話,會報語法錯誤。

es2018中取消了tagged 模板中對於轉義字元的限制,正常解析的話可以正常獲取轉義字元的值,否則的話返回undefined。

function latex(str) { 
 return { "cooked": str[0], "raw": str.raw[0] }
} 

latex`unicode`
// { cooked: undefined, raw: "unicode"}

複製程式碼

可以看到我們通過str[0]去獲取轉義字元的值並不會報錯。通過str.raw[0]可以正常取得字串”unicode”。

正則相關的特性

s (dotAll)模式

我們知道元字元.無法匹配

u{2048} u{2049}等換行符。

在 ES2018 中為正規表示式增加了一個新的標誌 s 用來表示屬性dotAll。以使 .可以匹配任意字元, 包括換行符。

const re = /foo.bar/s;
re.test(`foo
bar`);
// → true
re.dotAll
// → true
re.flags
// → `s`
複製程式碼

命名捕獲組 named capture groups

正規表示式中可以通過數字索引來引用()語法捕獲的部分匹配結果。如

let re = /(d{4})-(d{2})-(d{2})/;
let result = re.exec(`2015-01-02`);
console.log(result[1],result[2],result[3]);
// 2015, 01, 02
複製程式碼

es2018中提供了命名捕獲組的功能。我們可以通過(?<name>...)語法給捕獲組命名。

let re = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/u;
let result = re.exec(`2015-01-02`);
// result.groups.year === `2015`;
// result.groups.month === `01`;
// result.groups.day === `02`;
複製程式碼

或者以解構語法簡化程式碼:

let {groups: {year, month, day}} = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/u.exec(`2015-01-02`);
console.log(`year: ${year}, month: ${month}, day: ${day}`);  // prints year: 2015, month: 01, day: 02
複製程式碼

後行斷言

es5中,正則只支援先行斷言。例如:

正向先行斷言/x(?=y)/表示字元x後面的位置必須是y。

負向先行斷言/x(?!y)/表示x字元後面的位置不能等於y。

es2018中新增了後行斷言的支援。例如:

/(?<=y)x/表示字元x前面的位置必須是y。

/(?<!y)x/表示字元x前面的位置不能是y。

let re = /(?<=java)script/;
consle.log(re.test(`javascript`));
// true
複製程式碼

Unicode property escapes

Unicode property escapes使得可以在js正規表示式中本地訪問這些Unicode字元屬性。 例如,模式p {Script_Extensions = Greek}匹配希臘指令碼中的任意符號。

const regexGreekSymbol = /p{Script_Extensions=Greek}/u;
regexGreekSymbol.test(`π`);
// → true
複製程式碼

可選的catch引數

es2018對語法進行了修改,catch在沒使用引數的情況下省略括號。例如:

try {
  // try to use a web feature which may not be implemented
} catch (unused) {
  // fall back to a less desirable web feature with broader support
}
複製程式碼

上述程式碼在新規範下可以寫成:

try {
  // try to use a web feature which may not be implemented
} catch {
 // 省略catch後的函式括號
}
複製程式碼

JSON 超集

我們知道es5中通過JSON.parse可以將json字串轉換成js的json物件。但有例外,那就是當json文字中存在未轉義的換行符如u2028,u2029時,js中會報語法錯誤。

es2018中做了擴充套件,支援了所有的json文字,因此同樣允許未轉義的換行符的存在。

const LS = "
";
const PS = eval("`u2029`");
複製程式碼

上述程式碼片段在實現了es2018規範的瀏覽器中是不會出現語法錯誤的,反之則會報語法錯誤。自己可以試一下。

相關文章