生成器 迭代器 总结

70 阅读1分钟

iterator 迭代器 /generator 生成器

迭代器(iterator)

帮助我们对某个数据结构进行遍历的对象 在js中 迭代器也就是一个具体的对象 这个对象需要符合迭代器协议 迭代器协议:定义了产生一系列(无论是有限还是无限个)的标准方式 在js中这个标准就是一个特定的next方法 next方法有如下要求 **1. 一个无参函数或一个参数 返回一个应当拥有两个属性的对象 2. done(boolean)当迭代完成 则返回一个true 否则返回一个false 3. value 则是返回任何迭代的元素

const names = ['abc', 'nba', 'sja'];

let index = 0;
const iterator = {
  next: function () {
    if (index < names.length) {
      return { done: false, value: names[index] };
    } else {
      return { done: true, value: undefined };
    }
  },
};

function createArrayIteratou(arr) {
  let index = 0;
  return {
    next: function () {
      if (index < arr.length) {
        return { done: false, value: arr[index++] };
      } else {
        return { done: true, value: undefined };
      }
    },
  };
}

可迭代对象

当一个对象实现了可迭代协议(iterale protocol)协议 实现一个@@iterable 但是js中就是[Symbol.iterator]函数 const iterableObj = { [symbol.iterator] : function () { return 迭代器} } for of 可以遍历的东西必须是一个可迭代对象 for of 其实就是可迭代对象的语法糖 item 就是迭代器中的 value

// 可迭代对象
const iterableObj={
   names:['abc', 'nba', 'sja']
   [Symbol.iterator]:function(){
    let index =0
    return {
      next : ()=>{
        if (index < this. names.length) {
          return { done: false, value: this.names[index++] };
        } else {
          return { done: true, value: undefined };
        }
      }
    }
   }
}

// 每一次都是一个新的对象
const iterator1= iterableObj[Symbol.iterator]
console.log(iterator1.next())
const data=iterator1.next()

// for of 可以遍历的东西必须是一个可迭代对象  for of 其实就是可迭代对象的语法糖运用的就是迭代器中的next item就是迭代器中的value

for(const item of iterableObj){
   console.log(item)
}

展开运算符 对象没是没有迭代器的 但是在展开运算符时候做了一种特殊的语法 他把对象的key和value 都取出来了 之后重新组合

结构赋值 const [name1,name2]=names 他也是通过迭代器中的next 一个一个吧value传进去

生成器(一个特殊的迭代器) ES6中新增的一种函数控制 使用方案 它可以让我们更加灵活的控制函数什么时候继续执行,暂停执行等 *- 需要在function 后面加个 **- 可以通过yield关键字来控制函数的执行流程 - 生成器返回的是一个Generator(生成器) 调用生成器会返回一个生成器对象(特殊的迭代器 可以有next) const generator=foo() 开始执行第一段代码 generator.next() 开始执行第二段代码 generator.next()

class Classroom {
  constructor(address,name,students){
    this.address=address
    this.name=name
    this.students=students
  }

  entry(newStudent){
    this.students.push(newStudent)
  }

  [Symbol.iterator] (){
    let index=0
    return {
      next:()=>{
      if(index<this.students.length){
      return {done:false,value:this.students[index++]}
      }else{
        return {done:ture,value:undefined}
      }
      },
      return:()=>{
        console.log('停止了')
        return {done:true,value:undefined}
      }
    }
  }
}

const classroom = new Classroom('aaa','bbbb',[123,456,789])


// 生成器函数
function* foo(a){
console.log('函数的开始')
 const n= yield '123'
console.log('函数的')
let a =100*n
yield a
}

const generator =foo()
// 开始执行第一段代码
generator.next()
// 开始执行第二段代码
generator.next()

// 终止了 相当于在这一段代码加了return 并且返回值是11
generator.return(11)

// 可以通过try catch 来捕获到异常 可以继续调用next
generator.throw(22)

当遇见yield会暂停执行 当遇见return的时候会停止执行 在yield后面 加上值 这个就是这段代码的返回值 当执行第二段代码时候想要传入值需要在 next(10) 这个10就是上一段代码yield的返回值 const N = yield 11