Fork me on GitHub

ES9

ES2018 新特性

for await...of

在异步或者同步可迭代对象上创建一个迭代循环,包括String,Array,Array-like对象(比如arguments或者NodeList),TypedArray,Map,Set和自定义的异步或者同步迭代对象。其会调用自定义迭代钩子,并为每个不同属性的值执行语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
async function* asyncGenerator() {
var i = 0
while (i < 3) {
yield i++
}
}

(async function() {
for await (num of asyncGenerator()) {
console.log(num)
}
})()
// 0
// 1
// 2

模板字符串

ES9 开始,模板字符串允许嵌套支持常见转义序列,移除对 ECMAScript 在带标签的模板字符串中转义序列的语法限制。
不过,非法转义序列在”cooked”当中仍然会体现出来。它们将以undefined元素的形式存在于”cooked”之中,代码如下:

1
2
3
4
5
6
7
8
function latex(str) {
return {
"cooked": str[0],
"raw": str.raw[0]
}
}

console.log(latex `\unicode`) // { cooked: undefined,//转义后的字符 raw: "\unicode" }

.finally(()=>{})

同.catch(),.then()一样用于异步操作
不管异步操作状态变为 reject 还是 resolve 都会执行 finally 中的回调函数,
表示异步操作已经执行完了

正则表达式新特性

  • 点匹配符 dotAll,匹配除了换行符(\n 或\r)之外的所有字符
    如果想要匹配所有字符可以使用\d\D表示一切数字和非数字。
1
2
3
4
5
6
7
8
let regex = /./;

regex.test('\n'); // false
regex.test('\r'); // false
regex.test('\u{2028}'); // false
regex.test('\u{2029}'); // false
/one\.two/.test('one\ntwo') //false
/one[\d\D]two/.test('one\ntwo') //true

ES2018 可以使用 s 标志配合./dotAll 匹配符,匹配所有的字符

1
2
/one\.two/s.test('one\ntwo') //true
/s 表示将字符串视为单行来匹配
  •  匹配组命名
1
2
3
4
5
6
const re=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match=re.exec('2019-01-10');
console.log(match.groups);// {year:'2019',month:'01',day:'10'}
console.log(match.groups.year) //2019
console.log(match.groups.month) //01
console.log(match.groups.day) //10

 可以使用 \k<name> 使用前面已经命名过得分组名称

1
2
3
4
5
6
7
8
9
10
const re=/\b(?<dup\w+>\s+\k<dup>\b/
\b单词边界
\w+匹配一个或多少个数字、字母、下划线
\s+匹配一个或多个空格
使用<?dup> 表示匹配一个由一个或多个数字字母下划线组成的字符串,然后后面有一个或多个空格,后面是跟前面dup匹配到的一样的字符串
所以上面的正则表达式是匹配两个相同的用空格连接的单词

const match re.exec('Get that that cat off the table!')
match.index //4,匹配成功开始字符的下标
match[0] //that that

在 replace 函数里面使用\$<name> 实现替换

1
2
3
const str='red & blue';
str.replace(/(red) & (blue)/, '$2 & $1');
str.replace(/(?<red>red) & (?<blue>blue)/, '$<blue> & $<red>')

正则表达式反向(lookbehind)断言

断言是一个对当前匹配位置之前或之后的字符的测试,它不会实际消耗任何字符,所以断言也被称为非消耗性匹配或非获取匹配。

  • (?<=pattern)零宽反向肯定断言

    1
    2
    3
    4
    5
    6
    7
    8
    9
    const re=/(?<=\$|£|€)\d+(\.\d*)?/;
    re.exec('199')
    //null
    re.exec('$199)
    //['199',undefined,index:1,input:'$199',groups:undefined]
    re.exec('€50')
    //["50", undefined, index: 1, input: "€50", groups: undefined]
    'abc123'.match(/(?<=(\d+)(\d+))$/)
    // ["", "1", "23", index: 6, input: "abc123", groups: undefined]
  • (?<!pattern)零宽反向否定断言

    1
    2
    3
    4
    5
    const re=/(?<!un)available/;
    re.exec('We regret this service is currently unavailable')
    // null
    re.exec('this service is available)
    // ["available", index: 15, input: "The service is available", groups: undefined]
  • 正则表达式 Unicode 转义
    \d 仅匹配数组字符[0,9]
    \p{类型} 匹配某一类型的字符
    匹配所有数字

    1
    2
    3
    4
    const regex = /^\p{Number}+$/u;
    regex.test('²³¹¼½¾') // true
    regex.test('㉛㉜㉝') // true
    regex.test('ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ') // true

    匹配所有空格

    1
    \p{White_Space}

    匹配字母

    1
    2
    3
    const str='ض';
    /\p{Alphabetic}/u.test(str) //true
    /\w/u.test(str) //false

    否定匹配 \P{}

    1
    2
    3
    4
    5
    /\P{Number}/u.test('㉛')  //false
    /\P{Number}/u.test('ض') //true

    /\P{Alphabetic}/u.test('㉛') //true
    /\P{Alphabetic}/u.test('ض') //false

对象扩展操作符

Promise.prototype.finally()

返回一个Promise,当 promise 的状态变更,不管变成rejectedfulfilled,最终都会执行finally()的回调。

-------------本文结束感谢阅读-------------