⑦ ES7 异步迭代&对象操作升级

1 异步迭代:for await of

1.1 同步迭代(模拟)

const arr = ['es6', 'es7', 'es8', 'es9']
// 只适用于同步操作
arr[Symbol.iterator] = function() {
  let nextIndex = 0
  return {
    next() {
      return nextIndex < arr.length ? {
        value: arr[nextIndex+1],
        done: false
      } : {
        value: undefined,
        done: true
      }
    }
  }
}
for(let item of arr) {
  console.log(item);
}

1.2 异步迭代

  • for await of

  • Symbol.asyncIterator

function getPromise(time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        value: time,
        done: false
      })
    }, time);
  })
}
const arr = [getPromise(1000), getPromise(2000), getPromise(3000)]
arr[Symbol.asyncIterator] = function() {
  let nextIndex = 0
  return {
    next() {
      return nextIndex < arr.length ? arr[nextIndex++]
      : Promise.resolve({
        value: undefined,
        done: true
      })
    }
  }
}
async function test() {
  for await (let item of arr) {
    console.log(item);
  }
}
test()

2 正则表达式扩展:dotAll,具名组匹配,后行断言

2.1 dotAll

  • 正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是有两个例外

    • 一个是四个字节的 UTF-16 字符,这个可以用 u 修饰符解决

    • 另一个是行终止符(line terminator character)

      • \n \r 行分隔符\u{2028} 段分隔符\u{2029}
const reg = /./
console.log(reg.test('5')); // true
console.log(reg.test('x')); // true
console.log(reg.test('\n')); // false
console.log(reg.test('\u{2028}')); // false

const regs = /./s
console.log(regs.test('5')); // true
console.log(regs.test('x')); // true
console.log(regs.test('\n')); // true
console.log(regs.test('\u{2028}')); // true

2.2 具名组匹配

const date = /(\d{4})-(\d{2})-(\d{2})/.exec('2022-04-26')
console.log(date); // [ "2022-04-26", "2022", "04", "26"]

const reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
// console.log(reg.exec('2022-04-26'));
// [ "2022-04-26", "2022", "04", "26", groups: { day: "26", month: "04", year: "2022" }, index: 0, input: "2022-04-26" }
const groups = reg.exec('2022-04-26').groups
const { year, month, day} = groups

2.3 后行断言

  • 后行断言 先行断言
const str = 'ecmascript'
// 先行断言 匹配后面跟着script的ecma ①先匹配ecma ②判断后面是否script
console.log(str.match(/ecma(?=script)/)); // ['ecma', ...]

// 后行断言 匹配前面跟着ecma的script ①先匹配script ②判断前面是否ecma
console.log(str.match(/(?<=ecma)script/)); // ['script', ...]
console.log(str.match(/(?<!ecma)script/)); // null

3 对象扩展:Rest & Spread

3.1 Spread

const obj1 = {
  name: 'zouzou',
  age: 12
}
const obj2 = {
  school: 'imooc'
}

1. 克隆

const obj3 = { ...obj1 }
obj2.age = 13
console.log(obj3); // { name: 'zouzou', age: 12 }

2. 合并对象

const obj4 = { ...obj1, ...obj2 }
console.log(obj4); // {name: 'zouzou', age: 13, school: 'imooc'}

3.2 rest

  • 剩余运算
const obj1 = {
  name: 'zouzou',
  age: 12,
  school: 'imooc',
  course: 'es'
}
const { name, age, ...rest } = obj1
console.log(rest); // {school: 'imooc', course: 'es'}

4 Promise扩展:Promise.prototype.finally()

  • 指定不管最后状态如何都会执行的回调函数
  1. 返回一个 Promise,在 promise 执行结束时,无论结果是 fulfilled 或者是 rejected,在执行 then() 和 catch() 后,都会执行 finally 指定的回调函数。

  2. 这为指定执行完 promise 后,无论结果是 fulfilled 还是 rejected 都需要执行的代码提供了一种方式,避免同样的语句需要在 then() 和 catch() 中各写一次的情况。

new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
    reject('fail')
  }, 1000);
}).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
}).finally(() => {
  console.log('finally');
})

应用

  • 不管执行成功 | 失败 之后都要执行的操作
  1. loading 关闭

  2. 数据库断开连接

5 字符串扩展:放松模板字符串文字限制

5.1 带标签的模板字符串

const foo = (a, b, c, d) => {
  console.log(a);
  console.log(b);
  console.log(c);
  console.log(d);
}
const name = 'zouzou'
const age = 12
foo`这是${name},他今年${age}岁`
// ['这是', ',他今年', '岁', row: [...]], zouzou, 12

5.2 限制


const foo = arg => {
  console.log(arg);
}
foo`\u{61} and \u{62}` // ['a and b', row: [...]]
foo`\u{61} and \uncode` // ['undefined, row: [...]]
posted on 2022-05-18 17:37  pleaseAnswer  阅读(47)  评论(0编辑  收藏  举报