前言设计模式是一个程序员进阶进阶的必备技能,也是衡量一个工程师工作经验和能力的试金石。设计模式是程序员多年经验的浓缩和综合总结,可以更大程度的优化代码,合理重构已有代码。作为一名合格的前端工程师,学习设计模式是总结和反思自己工作经验的另一种方式,也是开发高质量、高可维护性和可扩展性代码的重要手段。我们熟悉的几大框架,jquery、react、vue,其内部也使用了大量的设计模式,如观察者模式、代理模式、单例模式等。因此,作为架构师,设计模式必须被掌握。在中高级前端工程师的面试过程中,面试官也会适当考察求职者对设计模式的理解程度。因此,笔者结合多年的工作经验和学习探索,总结并绘制了javascript设计模式的思维导图和实际案例,让我们一起探索学习。你将获得单例模式、构造器模式、建造者模式、代理模式、外观模式、观察者模式、策略模式、迭代器模式、文本,我们先来看看概览。设计模式能给我们带来什么?上面作者主要总结了几点设计模式可以给工程带来的好处,比如代码解耦、可扩展性、可靠性、有序性和可重用性。让我们来看看我们的第一个JavaScript设计模式。1.单例模式1.1概念解释单例模式:保证一个类只有一个实例,一般先判断该实例是否存在,如果存在则直接返回,如果不存在则先创建再创建然后返回它,这样可以保证一个类只有一个实例对象。1.2功能模块之间的通信。保证某一类对象的唯一性。防止变量污染。1.3注意事项正确使用。闭包容易造成内存泄漏,所以要及时清除不需要的变量。创建一个新对象是昂贵的。1.4实际案例单例模式广泛应用于不同的编程语言中。广泛应用于实际软件应用中,如电脑任务管理器、回收站、网站计数器、多线程线程池设计等。1.5代码实现(function(){//养鱼游戏letfish=nullfunctioncatchFish(){//如果鱼存在,直接返回if(fish){returnfish}else{//如果鱼不存在,得到它Fishreturnsfish=document.querySelector('#cat')return{fish,water:function(){letwater=this.fish.getAttribute('weight')this.fish.setAttribute('weight',++water)}}}}//每3小时喂水一次setInterval(()=>{catchFish().water()},3*60*60*1000)})()2.2.1构造器模式概念解释构造器模式:用来创建特定类型的对象,以实现可重用的业务逻辑和功能。2.2角色创建特定类型的对象。逻辑和业务的封装。2.3注意事项注意划分业务逻辑的边界。配合单例实现初始化等工作。构造函数命名约定,首字母大写。新对象的成本,将公共方法放在原型链上。2.4实战构造函数模式我认为是代码的模式,也是用来检验程序员对业务代码的理解程度。常用于实现javascript工具库,如lodash、javascript框架等。2.5代码展示functionTools(){if(!(thisinstanceofTools)){returnnewTools()}this.name='jstoollibrary'//获取dom的方法this.getEl=function(elem){returndocument.querySelector(elem)}//判断是否为数组this.isArray=function(arr){returnArray.isArray(arr)}//其他常用方法...}3.Builder模式3.1概念解释Builder模式:通过有序的分工,逐步实现一个复杂的逻辑或功能。3.2角色分配创建复杂对象或实现复杂功能。解耦封装过程,不用关注具体创建的细节。3.3防范措施需要有可靠的算法和逻辑支持。根据需要公开某些接口。3.4实际案例建造者模式实际应用在很多领域。笔者之前写过很多js插件,大部分都是采用builder模式。可以到作者的github地址许小希的github学习。其他情况如下:jqueryAjax封装。jquery插件包。react/vue的一个具体组件的设计。3.5代码展示笔者举了一个之前使用builder模式实现的案例:Canvas入门javascript面向对象实现一个图文验证码,接下来让我们使用builder模式实现一个很常见的验证码插件!//canvas绘制图形验证码(function(){functionGcode(el,option){this.el=typeofel==='string'?document.querySelector(el):el;this.option=option;this.init();}Gcode.prototype={constructor:Gcode,init:function(){if(this.el.getContext){isSupportCanvas=true;varctx=this.el.getContext('2d'),//设置画布宽高cw=this.el.width=this.option.width||200,ch=this.el.height=this.option.height||40,textLen=this.option.textLen||4,lineNum=this.option.lineNum||4;vartext=this.randomText(textLen);this.onClick(ctx,textLen,lineNum,cw,ch);this.drawLine(ctx,lineNum,cw,ch);这.drawText(ctx,文本,ch);}},onClick:函数(ctx,textLen,lineNum,cw,ch){var_=this;this.el.addEventListener('click',function(){text=_.randomText(textLen);_.drawLine(ctx,lineNum,cw,ch);_.drawText(ctx,text,ch);},false)},//绘制干线drawLine:function(ctx,lineNum,maxW,maxH){ctx.clearRect(0,0,maxW,maxH);for(vari=0;i
