for await of
异步操作集合的遍历
function Gen(time) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(time), time)
})
}
async function test() {
let arr = [Gen(2000), Gen(100), Gen(3000)]
for await (let item of arr) {
console.log(Date.now(), item)
}
}
test()
// for await of 需要 [Symbol.asyncIterator]
const obj = {
count: 0,
Gen(time) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve({ done: false, value: time }), time)
}),
[Symbol.asyncIterator]() {
let self = this
return {
next() {
self.count++
if (self.count < 4) {
return self.Gen(Math.random() * 1000)
} else {
return Promise.resolve({
done: true,
value: undefined
})
}
}
}
}
}
更多内容详见:异步迭代器和异步可迭代协议
Promise
Promise.prototype.finally()
Object
对象的解构和扩展运算符
const o1 = { a: 1, b: 2 }
const o2 = { c: 3 }
const o3 = {
...o1,
...o2,
a: 99,
d: 4
}
o1.b = 100
console.log(o3) // { a: 99, b: 2, c: 3, d: 4 }
// 解构 + 剩余参数
const { a, ...rest } = o3
RegExp
dotAll
RegExp 中 .
匹配不了的字符:
- 4 位以上的 unicode
// 使用 u 修饰符解决
/𠮷{2}/.test('𠮷𠮷') // false
/𠮷{2}/u.test('𠮷𠮷') // true
\n
等转译字符
// 使用 s 修饰符解决
/foo.bar/.test('foo\nbar') // false
/foo.bar/s.test('foo\nbar') // true
总结:/./us
,.
就全能了
const re1 = /foo.bar/
const re2 = /foo.bar/s
re1.dotAll // false
re2.dotAll // true
// --------------------------------
// 其他判断方法
const re = /foo.bar/usgi
re.flags // "gisu"
命名分组捕获
const t = '2019-06-07'.match(/(\d{4})-(\d{2})-(\d{2})/)
/*
{
0: "2019-06-07" // 完整匹配
1: "2019" // 第一个分组
2: "06" // 第二个分组
3: "07" // 第三个分组
groups: undefined // 分组
index: 0 // 正则是从第几个字符匹配到的
input: "2019-06-07" // 输入字符串
length: 4
}
*/
t[1] // 2019
t[2] // 06
t[3] // 07
// ES9 之前这样写,非常不清晰,不方便
// ----------------------------
// ES9:命名分组捕获
const t2 = '2019-06-07'.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/)
/*
{
0, 1 ,2, 3, index, input ,length, // 同上
groups: {
{ year: "2019", month: "06", day: "07" }
}
}
*/
t2.groups.year // 2019
t2.groups.month // 06
t2.groups.day // 07
后行断言
先行断言:
const test = 'hello world'
test.match(/hello(?=\sworld)/) // hello 后要紧跟 \sworld
// 先行断言:先遇到一个条件,再判断后面的是否满足
/*
{
0: "hello"
groups: undefined
index: 0
input: "hello world"
length: 1
}
*/
后行断言:
const test = 'hello world'
test.match(/(?<=hello\s)world/) // world 前面是不是 hello\s
// 后行断言:已经“走”过去了,再“退回来”判断
/*
{
0: "world"
groups: undefined
index: 6
input: "hello world"
length: 1
}
*/
// 匹配失败就返回 null
test.match(/(?<=hells\s)world/) // null
// 判断不等于
test.match(/(?<!hells\s)world/)