• 设计模式-迭代器模式


    介绍

    • 顺序访问一个集合
    • 使用者无需知道集合的内部结构(封装)

    示例

    • 常用的jQuery演示
    <p>jquery each</p>
    <p>jquery each</p>
    <p>jquery each</p>
    
    <script>
    var arr = [1,2,3]
    var nodeList = document.getElementsByTagName('p')
    var $p = $('p')
    
    // 要对这三个变量进行遍历,需要写三个遍历方法
    // 第一
    arr.forEach(function(item){
        console.log(item)
    })
    
    // 第二
    var i, length = nodeList.length
    for(i = 0; i < length; i++) {
        console.log(nodeList[i])
    }
    
    // 第三
    $p.each(function (key, p){
        console.log(key, p)
    })
    
    function each(data) {
        var $data = $(data)
        $data.each(function (key, val){
            console.log(key, val)
        })
    }
    each(arr)
    each(nodeList)
    each($a)
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    UML类图

    • 传统UML类图
      传统UML类图
    • 简化UML类图
      简化简化UML类图UML类图

    代码演示

    class Iterator {
        constructor(container) {
            this.list = container.list
            this.index = 0
        }
        next() {
            if (this.hasNext()) {
                return this.list[this.index++]
            }
            return null
        }
        hasNext() {
            if (this.index >= this.list.length) {
                return false
            }
            return true
        }
    }
    class Container {
        constructor(list) {
            this.list = list
        }
        // 生成遍历器
        getIterator() {
            return new Iterator(this)
        }
    }
    
    let arr = [1, 2, 3, 4, 5, 6]
    let container = new Container(arr)
    let iterator = container.getIterator()
    while(iterator.hasNext()) {
        console.log(iterator.next())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    场景

    • jQuery each
    • ES6 Iterator

    ES6 Iterator为何存在?

    • ES6语法中,有序集合的数据类型已经有很多
    • Array Map Set String TypedArray arguments NodeList
    • 需要有一个统一的遍历接口来遍历所有数据类型
    • (注意,object不是有序集合,可以用Map代替)

    ES6 Iterator是什么?

    • 以上数据类型,都有[Symbol.iterator]属性
    • 属性值是函数,执行函数返回一个迭代器
    • 这个迭代器就有next方法可顺序迭代子元素
    • 可运行Array.prototype[Symbol.iterator]来测试

    ES6 Iterator示例

    function each(data) {
        // 生成迭代器
        let iterator = data[Symbol.iterator]()
        
        console.log(iterator.next()) // 有数据时返回 { value: 1, done: false }
        
        let item = {done: false}
        while (!item.done) {
            item = iterator.next()
            if (!item.done) {
                console.log(item.value)
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试代码

    let arr = [1, 2, 3, 4]
    let nodeList = document.getElementByTagName('p')
    let m = new Map()
    m.set('a', 100)
    m.set('b', 200)
    
    each(arr)
    each(arr)
    each(m)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    // `Symbol.iterator`并不是人人都知道
    // 也不是每个人都需要封装一个each方法
    // 因此有了 `for...of`语法
    function each(data) {
        for (let item of data) {
            console.log(item)
        }
    }
    
    each(arr)
    each(nodeList)
    each(m)
    
    // for of 遍历迭代器
    // for in 遍历对象
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    ES6 Iterator 与 Generator

    • Iterator的价值不限于上述几个类型的遍历
    • 还有Generator函数的使用
    • 即只要返回的数据符合Iterator接口的要求
    • 即可使用Iterator语法,这就是迭代器模式

    设计原则验证

    • 迭代器对象和目标对象分离
    • 迭代器将使用者与目标对象隔离开
    • 符合开放封闭原则
  • 相关阅读:
    如何实现应用程序的身份认证和数据加密?
    若依 数据权限图文详细理解及改造
    MATLAB中的符号计算是什么?如何使用它?
    PHP PDO
    黑马JVM总结(十九)
    【Java】【设计模式】单例模式
    WebAssembly核心编程[3]: Module 与 Instance
    【pytorch】数据加载dataset和dataloader的使用
    给页面写一个炫酷的时钟特效【web前端】
    Spring Boot常见面试题
  • 原文地址:https://blog.csdn.net/linanran1027/article/details/133320922