设计模式-迭代器模式

2021-11-19  本文已影响0人  草珊瑚_6557

概念

官话

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

人话

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

理解概念

内部迭代器

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 接口的数据结构如下:

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

上一篇下一篇

猜你喜欢

热点阅读