16、生成器和迭代器

1、生成器(生成器与迭代器用法一样)

// 写法 function* 名称(){}
function* gen() {
  // yield关键字后面跟返回值(同步|异步都可以处理)
  yield '皇子' // 同步
  yield Promise.resolve('皇子') // 异步
  yield '小皇子' // 同步
}

// 生成器调用 next()
// const woman: Generator<"皇子" | Promise<string>, void, unknown>
const woman = gen()
console.log('第1次调用', woman.next()); // 第1次调用 { value: '皇子', done: false } 
console.log('第2次调用', woman.next()); // 第2次调用 { value: Promise { '皇子' }, done: false }
console.log('第3次调用', woman.next()); // 第3次调用 { value: '小皇子', done: false }
console.log('第4次调用', woman.next()); // 第4次调用 { value: undefined, done: true } 如果done:true说明没有东西可以迭代

2、迭代器

先熟悉 set、map

// set虽然与数组很像,但是它(只有数字和字符串)是天然去重的(对象不支持去重)
let set: Set<number> = new Set([1, 1, 5, 6, 3, 4, 2, 4, 2])
console.log('set:', set) // set: Set(6) { 1, 5, 6, 3, 4, 2 }
// Map接收两个类型key和value
let map: Map<any, any> = new Map()
// Map的key是可以使用引用类型的
let Arr = [1, 2, 3]
map.set(Arr, '我的key是2') // map.set()设置值
// map.get()取值
console.log(map.get(Arr)); // 我的key是2
console.log('map是:', map); // map是: Map(1) { [ 1, 2, 3 ] => '我的key是2' }

// function的arguments获取参数的集合,类数组
function args() {
  console.log(arguments);
}

// let list = document.querySelectorAll('div') // 也是一个类数组
// list.// 没有数组的方法,但是有forEach

  

写一个each方法,调用自身迭代器,实现遍历

// 写一个each方法,调用自身迭代器,实现遍历
const each = (value: any) => {
  // 第1步:获取迭代器
  let It: any = value[Symbol.iterator]() // 迭代器是个方法要先调用下
  // 第2步:定义默认值 next
  let next: any = { done: false }
  // 如果为true,就停掉循环
  while (!next.done) {
    // 把真正的next(It.next())赋值给自己定义的next
    next = It.next()
    // 打印出来
    if (!next.done) {
      console.log('结果是:', next.value);
    }
  }
}

// 调用
each(map) // 结果是: [ [ 1, 2, 3 ], '我的key是2' ]
each(set)
/*
结果是: 1
结果是: 5
结果是: 6
结果是: 3
结果是: 4
结果是: 2 */

// *each方法简写,迭代器的语法糖 for of
for (let value of map) {
  console.log('语法糖1:', value); // 语法糖1: [ [ 1, 2, 3 ], '我的key是2' ]
}

for (let value of set) {
  console.log('语法糖:', value);
}
/*
语法糖: 1
语法糖: 5
语法糖: 6
语法糖: 3
语法糖: 4
语法糖: 2 */

// *for of 对象不能用,因为对象中没有iterator
// let ob = { name: 'huangzi', age: 20 }
// for (let value of ob) { } // Type '{ name: string; age: number; }' must have a '[Symbol.iterator]()' method that returns an iterator

// 解构的底层原理是调用iterator
let a11: number[] = [6, 8, 9]
let [a, b, c] = [3, 2, 1]
let copyA11 = [...a11]

// 手动实现:对象支持for of
let oFn = {
  max: 5,
  current: 0,
  // 手动实现[Symbol.iterator]()方法,让对象支持for of、对象的解构
  [Symbol.iterator]() {
    return {
      max: this.max,
      current: this.current,
      next() {
        if (this.current === this.max) { // 迭代结束
          return {
            value: undefined,
            done: true
          }
        } else { // 迭代继续
          return {
            value: this.current++,
            done: false
          }
        }
      }
    }
  }
}

for (let value of oFn) {
  console.log('手动实现对象for of->', value)
}
/* 
手动实现对象for of-> 0
手动实现对象for of-> 1
手动实现对象for of-> 2
手动实现对象for of-> 3
手动实现对象for of-> 4 */

// 对象解构
let x = { ...oFn }
console.log('x->', x)
/*
x-> {
  max: 5,
  current: 0,
  [Symbol(Symbol.iterator)]: [Function: [Symbol.iterator]]
} */

// 对象解构与数组解构不一样
// 数组解构:底层调用的是Symbol的iterator
// 对象解构:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值