js手写-迭代器与生成器

发布于:2025-02-10 ⋅ 阅读:(33) ⋅ 点赞:(0)

迭代器

是一个对象,实现了迭代器协议
迭代器协议:由next方法,返回{value:,done:}

代码


function Iterator(arr) {

  let index = 0;

  return {

    next: function () {

      if (index < arr.length) {

        return {

          value: arr[index++],

          done: false,

        };

      } else {

        return {

          value: undefined,

          done: true,

        };

      }

    },

  };

}

//使用方式

const iterator = Iterator([1, 2, 3]);

console.log(iterator.next()); // { value: 1, done: false }

console.log(iterator.next()); // { value: 2, done: false }

console.log(iterator.next()); // { value: 3, done: false }

console.log(iterator.next()); // { value: undefined, done: true }

可迭代对象

可迭代对象,该对象实现了可迭代协议,
可迭代协议
内含Symbol.iterator方法,内含遍历的目标,索引指针,目标对应的迭代器,也就是包含了创建迭代器对象的方法

代码



const iterableObj = {

  //遍历的目标

  names: ["张三", "李四", "王五"],

  [Symbol.iterator]: function () {

    //索引指针

    let index = 0;

    //迭代器

    return {

      next: () => {

        if (index < this.names.length) {

          return {

            value: this.names[index++],

            done: false,

          };

        } else {

          return {

            value: undefined,

            done: true,

          };

        }

      },

    };

  },

};

//使用

let iterator = iterableObj[Symbol.iterator]();

console.log(iterator.next()); // { value: '张三', done: false }

console.log(iterator.next()); // { value: '李四', done: false }

console.log(iterator.next()); // { value: '王五', done: false }

console.log(iterator.next()); // { value: undefined, done: true }

for of原理

使用for…of,js引擎会自动调用可迭代对象的[Symbol.iterator]()方法,生成一个迭代器对象,然后调用这个迭代器对象的next方法不断获取value值,直到返回的对象的done==false结束

//1.定义一个可迭代对象

let obj = ["张三", "李四", "王五"]

function myof(obj){

    //1.获取迭代器

    const iterator = obj[Symbol.iterator]()

    //2.调用迭代器的next方法

    let res = iterator.next()

    while(!res.done){

        console.log(res.value);

        res = iterator.next()

    }

}

myof(obj)

原生可迭代对象

String,Array,Map,Set…
只能用于可迭代对象的操作

  • for…of
  • 展开语法
  • yield*
  • 解构赋值
    等等

展开语法可以用于对象
对象不是可迭代对象,主要用于对象是无序的,也就不支持遍历

展开语法展开对象

Object.keys(),values(),entries()

function mergeObj(obj){

    let res={}

    for(let key of Object.keys(obj))

    {

        res[key] = obj[key]

    }

    return res;

}

生成器

生成器函数

一种特殊的函数,能够在函数执行期间暂停和恢复执行,返回生成器对象

  • 生成器函数需要在function后面加*
  • 生成器函数可以通过yield来控制函数的执行流程
  • 生成器函数返回值是一个生成器

生成器对象

一个特殊的迭代器对象

function* generator(){

    console.log("start~~~");

    let valu1=100;

    console.log("第一段代码:",valu1);

    yield valu1;//生成器暂停

    let valu2=200;

    console.log("第二段代码:",valu2);

    yield valu2;//生成器暂停

    let valu3=300;

    console.log("第三段代码:",valu3);

    yield valu3;//生成器暂停

  

    console.log("end~~~");

}

  

let gen = generator();

console.log(gen.next());//{ value: 100, done: false }

console.log(gen.next());//{ value: 200, done: false }

console.log(gen.next());//{ value: 300, done: false }

console.log(gen.next());//{ value: undefined, done: true }

console.log(gen.next());//{ value: undefined, done: true }

自定义对象的可迭代性

class Room {

  constructor(name, students) {

    this.name = name;

    this.students = students;

  }

  entry(newStudent) {

    this.students.push(newStudent);

  }

  //1.使用普通函数

  // [Symbol.iterator](){

  //     let index=0;

  //     return {

  //         next:()=>{

  //             if(index < this.students.length){

  //                 return {

  //                     value:this.students[index++],

  //                     done:false

  //                 }

  //             }else{

  //                 return {

  //                     value:undefined,

  //                     done:true

  //                 }

  //             }

  //         }

  //     }

  // }

  //2.使用生成器函数

  *[Symbol.iterator]() {

    for (let i = 0; i < this.students.length; i++) {

      yield this.students[i];

    }

  }

}

  

let room = new Room("房间1", []);

room.entry("张三");

room.entry("李四");

  

for (let stu of room) {

  console.log(stu);

}

网站公告

今日签到

点亮在社区的每一天
去签到