• 深入理解ES6之——迭代器与生成器


    迭代器

    迭代器是被设计专用于迭代的对象,带有特定接口。所有的迭代器对象都有next方法,会返回一个结果对象。该结果对象有两个属性:对应下一个值的value,以及一个布尔类型的done,其值为true时表示没有更多对值可供使用。

    //es5创建迭代器
    function createIterator(items) {
    var i = 0;
    
    return {
        next: function() {
            var done = (i >= items.length);
            var value = !done ? items[i++] : "undefined";
    
            return {
                done: done,
                value: value
            }
        }
    }
    }
    
    var iterator = createIterator([1, 2, 3]);
    console.log(iterator.next());//{done:false,value:1}
    console.log(iterator.next());//{done:false,value:2}
    console.log(iterator.next());//{done:false,value:3}
    console.log(iterator.next());//{done:true,value:"undefined"}
    console.log(iterator.next());//{done:true,value:"undefined"}
    

    生成器

    生成器是一个能返回迭代器的函数。生成器函数由放在function关键字之后的一个星号(*)来表示,并使用新的yield关键字(指定迭代器在被next()方法调用时应当按顺序返回的值。)。

    function* createIterator() {
        yield 1;
        yield 2;
        yield 3;
    }
    
    var iterator = createIterator();
    
    console.log(iterator.next());//{done:false,value:1}
    console.log(iterator.next());//{done:false,value:2}
    console.log(iterator.next());//{done:false,value:3}
    console.log(iterator.next());//{done:true,value:undefined}
    console.log(iterator.next());//{done:true,value:undefined}
    

    生成器最有意思的方面可能就是它们会在每个yield语句后停止执行。

    //yield语句在for循环中的使用
    function* createIterator(items) {
        for (let i = 0, len = items.length; i < len; i++) {
            yield items[i];
        }
    }
    
    var iterator = createIterator([1, 2, 3]);
    
    console.log(iterator.next());//{done:false,value:1}
    console.log(iterator.next());//{done:false,value:2}
    console.log(iterator.next());//{done:false,value:3}
    console.log(iterator.next());//{done:true,value:undefined}
    console.log(iterator.next());//{done:true,value:undefined}
    

    yield只能用于生成器内部,用于其他任何位置都会报错,即使在生成器内部的函数中也不行。因为yield无法穿越函数边界。从这点上来说,yield与return非常相似。

    function *createIterator(items){
        items.forEach(function(item){
            yield item+1;//语法错误
        })
    }
    

    生成器函数表达式

    你可以使用函数表达式来创建一个生成器,只需要在function关键字与圆括号之间使用一个星号(*)即可。

    生成器对象方法

    var o = {
        *createIterator(items){
             for (let i = 0, len = items.length; i < len; i++) {
                    yield items[i];
                }
        }
    }
    

    可迭代对象与for-of循环

    可迭代对象被设计用于与es新增的for-of循环配合使用。

    for-of循环在循环每次执行时会调用可迭代对象的next()方法,并将结果对象的value储存在一个变量上。循环过程会持续到结果对象的done属性编程true为止。

    let values = [1, 2, 3];
    for (let num of values) {
        console.log(num);
    }
    
    //输出内容为
    1,2,3
    
    let set = new Set([1, 3, 3, 2, 4, 5, 1, 3]);
    
    for (let val of set) {
        console.log(val);
    }
    
    //输出内容为
    1,3,2,4,5
    
    let map = new Map();
    
    map.set("name", "cc");
    map.set("age", 26);
    
    for (let val of map) {
        console.log(val);
    }
    
    //输出内容为
    ["name","nicolas"]
    ["age",52]
    

    访问默认迭代器

    你可以使用Symbo.iterator来访问对象上的默认迭代器。

    let values = [1, 2, 3];
    
    var iterator = values[Symbol.iterator]();
    
    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}
    

    内置的迭代器

    集合的迭代器

    ES6具有三种集合对象类型:数组、Map和Set。这三种类型都拥有如下迭代器:

    1. entries():返回一个包含键值对的迭代器
    2. values():返回一个包含集合中值的迭代器
    3. keys():返回一个包含集合中键的迭代器
    let colors = ["red", "green", "blue"];
    let set = new Set([1234, 5678, 9012]);
    let map = new Map();
    
    map.set("title", "unde");
    map.set("format", "ebook");
    
    //entries
    for (let entry of colors.entries()) {
        console.log(entry);
    }
    for (let entry of set.entries()) {
        console.log(entry);
    }
    for (let entry of map.entries()) {
        console.log(entry);
    }
    
    //values
    for (let value of colors) {
        console.log(value);
    }
    for (let value of set.values()) {
        console.log(value);
    }
    for (let value of map.values()) {
        console.log(value);
    }
    
    //keys
    for (let key of colors.keys()) {
        console.log(key);
    }
    for (let key of set.keys()) {
        console.log(key);
    }
    for (let key of map.keys()) {
        console.log(key);
    }
    

    字符串的迭代器

    let message = "A  B";
    
    for (let s of message) {
        console.log(s);
    }
    
    //输出内容为
    A
    (BLANK)
    (BLANK)
    B
    

    NodeList的迭代器

    let p = document.getElementsByTagName("p");
    
    for (let c of p) {
        console.log(c.className);
    }
    

    传递参数给迭代器

    function* createIterator() {
        let first = yield 1;
        let second = yield first + 2;
        yield second + 3;
    }
    
    let iterator = createIterator();
    console.log(iterator.next());//1
    console.log(iterator.next(4));//6
    console.log(iterator.next(5));//8
    

    在包含赋值操作的第一个yield语句中,表达式右侧再第一次调用next()时被计算,而表达式左侧则在第二次调用next()方法时,并在生成器函数执行之前被计算。

    生成器委托

    function* createNumI() {
        yield 1;
        yield 2;
    }
    
    function* createColI() {
        yield "red";
        yield "green";
    }
    
    function* createComb() {
        yield* createNumI();
        yield* createColI();
        yield true;
    }
    
    let iterator = createComb();
    
    console.log(iterator.next());//{value:1,done:false}
    console.log(iterator.next());//{value:2,done:false}
    console.log(iterator.next());//{value:"red",done:false}
    console.log(iterator.next());//{value:"green",done:false}
    console.log(iterator.next());//{value:true,done:false}
    console.log(iterator.next());//{value:undefined,done:false}
    
  • 相关阅读:
    Apache ActiveMQ消息中间件的基本使用
    struts2结合生成验证码
    Python中docstring文档的写法
    Nginx+uWSGI+Django原理
    Python垃圾回收机制详解
    Python数据库连接池实例——PooledDB
    构建高可用服务端
    Python使用multiprocessing实现一个最简单的分布式作业调度系统
    python3 分布式进程(跨机器)BaseManager(multiprocessing.managers)
    python BaseManager分布式学习
  • 原文地址:https://www.cnblogs.com/xzsty/p/7866835.html
Copyright © 2020-2023  润新知