美文网首页
备忘录和迭代器模式

备忘录和迭代器模式

作者: 小宇cool | 来源:发表于2020-11-07 22:30 被阅读0次

1. 备忘录模式

1.1 定义

备忘录模式(Memeto) : 在不改变对象封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后使用.

1.2 作用

  1. 记录并保存对象的内部状态, 实现了对信息的缓存.
  2. 通过对象状态的缓存, 避免重复的去获取状态的操作.
  3. 允许对象能够恢复到原先的状态.可供一个可回滚的操作.

1.3应用场景

假设当我们通过一个点击按钮发送ajax请求拿到了后端返回的结果,当我们重复点击时会重复的发送ajax请求, 假设每次拿到的数据都是一样的,此时我们其实没必要每次点击都发送ajax请求, 因为这样会增加服务器的压力, 我们可以将第一次请求的结果保存起来,下次请求先进行判断是否已经得到过数据,在决定是否使用ajax.

很多分页的按钮原理都是一样的, 点击下一页, 发送请求拿到数据,在点上一页就没必要发送请求了, 因为数据已经展示过了, 保存起来用现成的数据就可以了,减少请求也是优化的关键.

 let btn = document.querySelector('#btn');
let request = function(key){
    // 缓存数据
    let cache = {};
    return async function(){
        /*如果缓存里面没有数据其
           发送请求成功后处理数据并放入数据
         */
        if(!cache[key]){
            const url = 'http://localhost:3000/goods';
            const response = await fetch(url);
            data = await response.json(); 
            // 处理数据
            result(data)
            //缓存数据
            cache[key] = data;
        }else{
            // 当缓存中有数据 直接处理
            result(cache[key])
        }
    }
}
//处理数据的函数
function result(data){}
btn.onclick = request(1)

总结 备忘录模式通常用来记录一个对象的内部状态, 给用户提供了一种恢复状态的机制, 可以使用户可以比较方便的回到某个历史的状态,实现了对象信息的缓存, 当缓存中有对应的数据时, 可以直接从缓存中去,避免重复去获取数据.

2. 迭代器模式

2.1 定义

迭代器模式(Iterator): 在不暴露对象内部结构的同时, 可以顺序地访问集合对象内部的各个元素.

看名字我们就可以发现, 其实JavaScript内中有很很多的迭代器了, 比如forEach, every, map,some,reduce,等等, 在ES6中迭代器的概念更加明显, 很多功能都是基于迭代器实现的.

2.2 作用

  1. 为不同的数据类型提供一种统一的遍历接口.实现对数据的遍历.
  2. 把遍历的操作交个迭代器, 我们只需要实现出具体的遍历操作.
  3. 简化了遍历对象的操作, 实现我们可以很方便得进行遍历.

2.3 应用场景

  • 内部迭代器

迭代的过程在方法内部完成, 也就是说我们不需要管迭代的进度,也没法管, 比如forEach

let list = document.getElementsByTagName('p');
[...list].forEach(item =>{
    console.log(item)
})

由于通过getElementsByTagName获取的DOM节点数据类型为HTMLCollection, 它是一个类数组对象, 不是数组对象, 所以它原型上并没有forEach方法, 我们通过spread运算符将其类型隐式转换了数组类型, 实现了对象集合对象的遍历.

用于forEach不兼容IE, 我们可以自己来简单实现

 Array.prototype.forEach = function(callback){
     for(let i =0,len =this.length;i < len; i++){
         callback(item,i,this)
     }
 }
  • 外部迭代器

需要我们手动操作, 才会进行下一次的遍历, ES6里面已经原生的实现了这个功能,通过.next()来操控迭代器对象:

let arr = [34,5,545];
let iterator = arr[Symbol.iterator]();
console.log(iterator.next())
// {value:34, done:false}
console.log(iterator.next())
// {value:5, done:false}
console.log(iterator.next())
// {value:545, done:false}
console.log(iterator.next())
// {value:undefined, done:true}

ES6内部在数组类型的数据上部署了Symbol.Iterator接口, 通过调用这个函数我们就可以返回一个迭代器对象, 通过调用迭代器对象的next方法我们可以从头到尾获取到数据的每一项数据, next方法返回一个对象 其中value属性为当前指向的数据,done表示是否已经完成了遍历.

自身实现一个外部迭代器

function MyIterator(arr) {
    let currentIndex = 0,
        length = arr.length;
    return {
        next() {
            return currentIndex > length
                ? { value: undefined, done: true } 
                : { value: arr[currentIndex++], done: false };
        }
    }
}

利用这个遍历器和循环我们可以属性对数组每项数据的读取

  function each(arr,callback){
      let iterator = MyIterator(arr);
      let result = iterator.next(),
          index = 0;// 用来当前遍历的下标
      // 当result的done不为true继续调用next方法
      while (!result.done) {
          callback(result.value,index++,arr);
          result = iterator.next();
      }
  }
 each([34,,4,54],(item) =>{
     console.log(item)
 })
  • 对象相关的迭代器与迭代器函数

ES6定义了Object.keys,Object.values,Object.entries等相关的方法, 让我们能方便的遍历对象的属性名或者属性值.同时也定义了for..of循环,ES6规定只要对象上部署了Symbol.Iterator遍历器生成方法, 就可以使用for...of循环.

let obj = { name: '张三', age: 43 };
for (let key of Object.keys(obj)){
    console.log(key)// name age
} 
for (let val of Object.values(obj)) {
    console.log(val)// 张三 43
} 
 for(let [key,val] of Object.entries(obj)){
     console.log([key,val])
     // ["name",'张三'] ["age": 43]
 }

上面的代码我们通过Object.keys,Object.values等方法实现了对对象的键名,键值,键值对的遍历, 因为这几个方法内部已经部署了Symbol.Iterator迭代器的生成函数,所以我们可以很方便的属性对象对象的遍历.

总结 通过迭代器模式可以实现对各种方式遍历,迭代器分离了集合对象的遍历过程,通过把迭代器抽象出来, 来实现出具体的遍历操作,这样使得可以在不暴露内部结构的情况下, 又可以让外部代码透明的访问集合内部的数据.

相关文章

  • Boolan C++设计模式第三周心得笔记

    单件模式 享元模式 状态模式 备忘录 组合模式 迭代器 职责链 命令模式 访问器 解析器 本周作业 本次作业要求针...

  • 设计模式| 行为型模式 (上)

    前言 行为型模式共十一种:策略模式、模板方法模式、观察者模式、迭代器模式、解释器模式、责任链模式、命令模式、备忘录...

  • 设计模式:行为型

    常用 观察者模式 策略模式 模版方法模式 迭代器模式 责任链模式 其他 命令 状态 解释器 访问者 中介者 备忘录

  • 备忘录和迭代器模式

    1. 备忘录模式 1.1 定义 备忘录模式(Memeto) : 在不改变对象封装性的前提下,在对象之外捕获并保存该...

  • 【设计模式】行为型设计模式汇总(二)

    行为型设计模式范围 观察者模式 模板方法 策略模式 职责链模式 状态模式 迭代器模式 访问者模式 备忘录模式 命令...

  • 【设计模式】行为型设计模式汇总(一)

    行为型设计模式范围 观察者模式 模板方法 策略模式 职责链模式 状态模式 迭代器模式 访问者模式 备忘录模式 命令...

  • C++设计模式-第三篇 (Boolan)

    C++设计模式-第三篇 (Boolan) 本章内容:1 备忘录模式2 状态模式3 组合模式4 迭代器模式5 职责模...

  • C++笔记十三(C++设计模式)

    本周内容(1)单件模式(2)享元模式(3)状态模式(4)备忘录(5)组合模式(6)迭代器(7)职责链(8)命令模式...

  • 「时间」2.3@

    2.3@ 目标: 1.java模式,迭代器,备忘录,命令模式 2.JavaScript语言 3.安卓开发视频 4....

  • 行为型-Iterator

    迭代器模式的原理和实现 迭代器模式(Iterator Design Pattern),也叫作游标模式(Cursor...

网友评论

      本文标题:备忘录和迭代器模式

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