美文网首页
设计模式-迭代器模式

设计模式-迭代器模式

作者: 草珊瑚_6557 | 来源:发表于2021-11-19 16:27 被阅读0次

    概念

    官话

    迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。

    人话

    按照顺序,从集合中依次取出数据。

    理解概念

    内部迭代器

    const each = ( ary, callback ) => {
        for ( var i = 0, l = ary.length; i < l; i++ ){
            // 把下标和元素当作参数传给 callback 函数
            callback.call( ary[i], i, ary[ i ] );
        }
    };
    
    each( [ 'a', 'b' , 'c' ], ( i, n ) => {
        console.log( [ i, n ] );
    });
    

    外部迭代器

    var o = {
        0: 1,
        1: 'a',
        2: 'b',
        3: 3,
        4: 4,
        length: 5,
    };
    
    // 定义外部迭代器,显式调用
    var Interator = function(obj) {
        var current = 0;
        var next = function() {
            current++;
        }
        var isDone = function() {
            return current >= obj.length;
        }
        var getCurrent = function() {
            return obj[current];
        }
        return {
            next,
            isDone,
            getCurrent,
        }
    }
    
    var interator = Interator(o)
    while (interator.isDone() === false) {
        // 依次输出 1, a, b, 3, 4
        console.log(interator.getCurrent())
        interator.next()
    }
    

    Iterator 接口的目的,就是为所有数据结构,提供了一种统一的访问机制。

    原生语言支持

    原生具备 Iterator 接口的数据结构如下:

    • Array
    • Map
    • Set
    • String
    • TypedArray
    • 函数的 arguments 对象
    • NodeList 对象
    let arr = ['a', 'b', 'c'];
    let iter = arr[Symbol.iterator]();
    
    iter.next() // { value: 'a', done: false }
    iter.next() // { value: 'b', done: false }
    iter.next() // { value: 'c', done: false }
    iter.next() // { value: undefined, done: true }
    iter.next() // { value: undefined, done: true }
    iter.next() // { value: undefined, done: true }
    

    使用场景

    扩展运算符和解构赋值

    // 例一
    var str = 'hello';
    [...str] //  ['h','e','l','l','o']
    
    // 例二
    let arr = ['b', 'c'];
    ['a', ...arr, 'd']
    // ['a', 'b', 'c', 'd'
    
    // 例三
    var [h,e] = [...str]
    

    for of循环

    // for...of 自动遍历拥有 Iterator 接口的数据结构
    let arr = [1, 2, 3];
    for (let item of arr) {
      console.log(item);
    }
    
    // 输出:1  2  3
    

    模式思考

    配合生成器和yield语法实现异步控制

    // *来声明这是一个生成器
    function *foo(){
        let x=10;
        let y=20;
      // yield是一个暂停点和一个表达式。yield的右边,是暂停时候的返回值(就是迭代器被调用next()后的返回值)。
        let z = yield x+y;
        return x + y +z;
    }
    //生成迭代器
    let fooIterator = foo();
    //第一次执行迭代器的next(),遇到 yield 返回,返回值是 yield 右侧的运行结果
    console.log(fooIterator.next().value); // 30
    //第二次执行迭代器的next(100), yield 及其右侧表达式的位置会替换为参数 100
    console.log(fooIterator.next(100).value); // 130
    
    
    function *fn(){
        yield new Promise(res=> setTimeout(function(){res(1)},500));
        yield new Promise(res=> setTimeout(function(){res(2)},500));
    }
    
    var gen = fn();
    
    while(!gen.next().done){
        Promise.resolve(gen.next().value)
    }
    
    

    和代理模式的比较

    迭代器模式是为所有数据结构提供一种统一的访问机制。
    代理模式是为隔离使用者和目标对象,仅通过代理使用目标对象的部分功能。
    两者都是为了不暴露目标对象的内部表示。

    参考

    https://es6.ruanyifeng.com/#docs/iterator

    相关文章

      网友评论

          本文标题:设计模式-迭代器模式

          本文链接:https://www.haomeiwen.com/subject/cwqetrtx.html