JavaScript -- 设计模式 行为型设计模式-迭代器模式

迭代器模式提供顺序访问聚合对象元素的方式,不暴露内部结构。在JavaScript中,ES6引入了迭代器,使得数组、Map等类型可通过`Symbol.iterator`属性和`for...of`循环进行遍历。本文通过代码示例介绍了如何使用迭代器模式及Generator函数实现遍历,包括对Object的遍历。
摘要由CSDN通过智能技术生成

迭代器模式:提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示。迭代器模式的特点在于顺序访问一个集合,使用者无需知道内部结构。

在现实生活中好像例子不多,但是熟悉ES6的工程师应该知道es6中有iterator。我们先不看这个,先写一个小的demo代码来熟悉迭代器。

我们先看一下迭代器的UML类图

 

class Iterator {
    constructor(container) {
        this.list = container.list;
        this.index = 0;
    }
    next() {
        if (this.hasNext()) {
            return this.list[this.index++];
        } else this.index++;
        return null;
    }
    hasNext() {
        return this.index < this.list.length;
    }
}
class Container {
    constructor(list) {
        this.list = list;
    }
    getIterator() {
        return new Iterator(this);
    }
}

const arr = [1, 2, 3, 4, 6];

const iter = new Container(arr).getIterator();
while (iter.hasNext()) {
    console.log(iter.next());
}

我们获取到迭代器对象后,无需关注迭代器是如何遍历子元素的,只需要简单的调用next函数即可。

 

ES6的iteractor你可能没有用过,但是for of循环你肯定使用过。

在JS当中,有很多有顺序的聚合对象比如array,map, set, nodeList, arguments,类数组,这些数据类型上面有一个Symbol.iterator属性,该值是一个函数用于返回一个迭代器,该迭代器上面有一个next函数。

const arr = [1, 2, 3, 4, 6];
const ite = arr[Symbol.iterator]();
console.log(ite);

我们来使用ES6的iterator来遍历该数组。

const arr = [1, 2, 3, 4, 6];
let iterator = arr[Symbol.iterator]();

let item = iterator.next();
while (!item.done) {
    console.log(item);
    item = iterator.next();
}

console.log(iterator.next());
console.log(iterator.next());

value:表示当前遍历的值  done表示是否结束 true表示结束

我们来封装一个each方法,来实现遍历。

const arr = [1, 2, 3, 4, 6];
const set = new Set();
set.add(1);
set.add(2);
set.add(3);
set.add(4);


function each(data) {
    let iterator = data[Symbol.iterator]();
    let item = iterator.next();
    while (!item.done) {
        console.log(item.value);
        item = iterator.next();
    }
}

console.log("数组遍历");
each(arr);
console.log("set遍历");
each(set);

这样其实很麻烦,幸好ES6封装了for of循环 这个我们就不掩饰了,非常简单。

 

Generator函数

function* list() {
    yield 1;
    yield 2;
    yield 3;
}
const l = list();
each(l);

Generator函数返回的是可以迭代的对象,我们可以使用each(上面封装的方法)或 for of来遍历。

 

我们知道Object没有迭代器,不能使用for of循环,那么我们可以通过Generator来实现for of遍历Obejct

function *getObjectIterator(obj) {
    for(let key in obj) {
        yield obj[key];
    }
}
const obj = { name: "cyl", age: 16 }
for (let v of getObjectIterator(obj)) {
    console.log(v);
}

 

我们可以利用Generator和for of来实现一些复杂的遍历,而且不必向调用者暴露细节。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值