JS:一篇理解迭代器和生成器

通过这篇文章你可以理解迭代器和生成器的一些概念和使用方法。如果想更深入的了解我推荐阅读MDN文档关于迭代器和生成器。同时,本篇文章也参考了网上的一些资料。

迭代器

  • 迭代器我理解为可控的迭代,而数组等是不可控迭代

  • 迭代器是一个对象

  • 必须有一个next()方法,通过 next() 方法实现迭代

    • 该方法返回一个对象,具有属性:value(序列中的next值)、done(最后一代为true)
    • 通过调用该方法迭代,直至迭代器消耗完
function createIterator(item){
    var i = 0;

    return {    // 返回一个迭代器对象
        next: function () {  //迭代器对象一定有next()方法
            var done = (i>item.length);
            var value = !done ? item[i++] : undefined;

            return {    //next()方法返回结果对象
                value: value,
                done: done
            }
        }
    }
}

var it = createIterator([10, 2, 3, 4, 5]);
console.log(it.next().value);       // 10
...
console.log(it.next().value);       // 5
console.log(it.next().value);       // undefined
  • ES6中为迭代器提供了统一的访问机制for...of,当使用for...of迭代可迭代对象时(Array、Set、Map和String),js引擎就会调用其Symbol.iterator属性上的方法,从而返回相应的默认迭代器。可以手动获取一下:
var arr = [10, 2, 3, 5];
// 默认迭代器对象
var it = arr[Symbol.iterator]();  
  • 由此可得,只要在自定义迭代器对象添加Symbol.iterator属性,就可以作为一个规范的迭代器使用for...of进行迭代。
...
    return {
        [Symbol.iterator]: function () { return this; },
        next: function () {
...
var it = createIterator([10, 2, 3, 4, 5]);
for(var v of it){   // 使用迭代器的循环机制遍历
    console.log(v);
}
  • 可以用Symbol.iterator来检测对象是否为可迭代对象:
function isIterator(obj) {
    // return typeof obj[Symbol.iterator] === "function";   // 这种方法也可以选用
    return Object.prototype.toString.call( obj[Symbol.iterator] )
           === "[object Function]";
}

生成器:

  • 生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield
  • 简化迭代器的创建过程,每遇到 yield 语句表示本次迭代完成,并且返回的对象中 value 为 yield 语句后的值。
  • 可以直接使用 for…of 进行迭代
function *createIterator(item) {
    for(let i=0; i<item.length; i++){
        yield item[i];
    }
}

var it = createIterator([10, 2, 4, 5, 6]);  // 生成器函数执行返回一个新的迭代器实例it
// 调用迭代器it的next()方法
console.log(it.next());   // {value: 10, done: false}
...
console.log(it.next());   // {value: 6, done: false}
console.log(it.next());   // {value: undefined, done: true}
  • next() 可以传递参数,将替换上一次 yield 语句返回的值
// 生成器
function *createIterator() {
    var first = yield 2;
    var second = yield first * 3;
    yield second + 3;
}

// 创建迭代器实例
var it = createIterator();

// 启动迭代器
it.next();      // {value: 2, done: false}
it.next(4);     // {value: 12, done: false}
it.next(7);     // {value: 10, done: false}
it.next();      // {value: undefined, done: true}

完结
——"Learning is the accumulation of experience, and ability is hard-working patience."

上一篇:Linux xsync分发脚本完整内容


下一篇:VMware Workstation15安装Centos7 Linux