javascript设计模式_JavaScript经常用的设计模式及其实现方式(一)

2421bcbef25b4873e8646ebc2fcf983d.png

最近小编在学习JS设计模式时,经常对其应用场景感到非常不明确。故而专门抽出时间总结一下并分享给大家。今天是第一期分享。

单例模式

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

实现:

用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象。

let Singleins = function(name){    this.name = name;    this.instance = null;}Singleins.prototype.getName = function(){    console.log(this.name)}Singleins.getInstance = function(name){    if(!this.instance){        this.instancee = new Singleins(name);    }    return this.instance;}let a = Singleins.getInstance('test1');let b = Singleins.getInstance('test2');alert(a === b);  //true

策略模式

定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。

实现:

策略模式的目的就是将算法的使用与算法的实现分离开来。利用JS实现的策略模式如下:

let strategies = {     "S":function(num){         return num * 4;     },     "A":function(num){         return num * 3;     },     "B":function(num){         return num * 2;     }};let useStrategy = function(level,num){    return strategies[level](num);};useStrategy('S', 2000); //8000useStrategy('A', 1000); //3000

代理模式

定义:为一个对象提供一个代用品或占位符,以便控制对它的访问。

实现:

代理模式按照作用可分为保护代理和虚拟代理两种形式。

  • 保护代理主要用于控制不同权限的对象对目标对象的访问。
  • 虚拟代理主要把一些开销很大的对象,延迟到真正需要它的时候才去创建。

在JS中,保护代理并不容易实现,因为我们无法判断谁访问了某个对象。而虚拟代理是最常用的一种代理模式。用虚拟代理的方式实现图片延迟加载功能:

let myImage = (function(){    let imgNode = document.createElement('img');    document.body.appendChild('imgNode');    return {        setSrc:function(src){            imgNode.src = src;        }    }})();let proxyImage = (function(){    let img = new Image();    img.onload = function(){        myImage.setSrc(this.src);    };    return {        setSrc:function(src){            myImage.setSrc('loading.gif');            img.src = src;        }    }})();proxyImage.setSrc('xxxxx.jpg');

这样实现图片延迟加载功能,更符合单一职责原则和开放-封闭原则。myImage只实现了给img节点设置src的功能,proxyImage只实现了给图片预加载loading图的功能,这样就避免了两种功能的强耦合。以后如果不需要loading图的预加载功能,可以直接不用proxyImage,不需要修改myImage。

迭代器模式

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

实现:

迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。迭代器可以分为内部迭代器和外部迭代器。

  • 内部迭代器
let each = function(ary,callback){    for(let i=0,l = ary.length;i
  • 外部迭代器
let Iterator = function(obj){   let current = 0;   let next = function(){       current +=1;   };      let isDone = function(){       return current>=obj.length;   };     let getCurrItem = function(){      return obj[current];  };    return {      next,      isDone,      getCurrItem,      length:obj.length  }};

本文部分内容摘自《JavaScript设计模式与开发实践》,若转载请注明出处,转发感激不尽。