当前位置: 首页 > Web前端 > HTML5

JavaScript学习笔记之设计模式

时间:2023-04-04 23:51:10 HTML5

优秀程序员web前端培训分享JavaScript学习笔记中的设计模式,设计模式是我们在解决问题的时候针对某个特定问题的一种简洁优化的解决方案我们有很多设计模式单例模式组合模式观察者模式。..今天我们就来说说这三种设计模式单例模式/组合模式/观察者模式单例模式什么是单例模式?·我们都知道一个构造函数可以创建一个对象·我们可以通过new构造函数多次得到很多对象·单例模式:使用构造函数实例化时,无论实例化多少次都是同一个对象·即,构造函数一生只能new出一个对象。也就是说,当我们使用构造函数时,每次新对象的属性/函数/方法都是完全一样的,我们将其设计为单例模式的核心代码。单例模式的核心代码非常简单。其实就是判断他是否曾经用new创建过一个对象。如果是,则继续使用之前的对象。如果没有,那就给你一个new_//准备一个结构体Function__//以后会new_functionPerson(){}_//准备一个单例模式函数//这个单例模式函数会让Person成为单例模式//以后要newPerson现在就执行这个单例函数。_functionsingleton(){letinstance;if(!instance){//如果instance没有内容_//来这里证明instance没有内容_//给他赋值newPersoninstance=newPerson()}//returnis始终是newPerson_的第一个实例_//始终是一个实例_返回实例}constp1=singleton()constp2=singleton()console.log(p1===p2)//真正的应用程序。下面我们利用这段核心代码简单的写一个demo_//这个构造函数的作用是创建一个div并添加到页面中_functionCreateDiv(){this.div=document.创建元素('div')文档。身体。追加孩子(这。div)}CreateDiv.prototype.init=function(text){this.div.innerHTML=text}_//准备把这个CreateDiv做成单例模式//把单例做成闭包函数_constsingleton=(function(){letinstancereturnfunction(text){if(!instance){instance=newCreateDiv()}instance.init(text)returninstance}})()singleton('hello')//第一次,页面会新建一个div出现,内容是hello_singleton('world')_//第二次,不会出现新的div,而是原来的div内容变成world组合模式。组合方式就是把几个构造函数的启动方法组合在一起,然后用一个“遥控器”统一调用classGetHome{init(){console.log('Home')}}classOpenComputer{init(){console.log('Turnonthecomputer')}}classPlayGame{init(){console.log('playingthegame')}}以上构造函数创建的实例化对象都是以同样的方式启动的。然后我们就可以用这些复合模式的形式写一个函数,然后一起启动准备复合模式的构造函数classCompose{constructor(){this.compose=[]}//添加任务的方法add(task){this.compose.push(task)}//一个执行任务的方法execute(){this.compose.forEach(item=>{item.init()})}}让我们使用我们的组合模式构造函数来前面几个函数的组合constc=newCompose()_//把所有要完成的任务放到队列中_c.add(newGetHome())c.add(newOpenComputer)c.add(newPlayGame)_//直接激活任务队列_c.execute()_//会依次执行三个对象中的init函数·官方解释:当一个对象的状态发生变化时,所有依赖它的对象都会得到通知并自动更新,解决了主体对象和观察者之间的功能耦合,即一个对象状态改变通知其他对象的问题.听起来很费解,但其实并不难。一个例子。当你想去书店买一本书,但恰好今天你想买的书没有货。我们不能一直在书店里等,所以我们把手机留给了店员。当你需要的书到了,他会打电话通知你。去买吧。你买完算了就告诉他我买了,等会儿我来拿书。我不会通知您有关addEventListener的信息。上面的例子可能不是很清楚。但是addEventListener是我们都用过的东西。这个东西其实就是一个标准的观察者模式btn.addEventListener('click',function(){console.log('btnwasclicked')})·上面就是有一个看不见的观察者在观察btn的一举一动。单击btn时,将执行相应的函数。我们还可以多绑定几个函数说白了:观察者模式就是自己实现一个addEventListener的函数。但是addEventListener只有一些固定事件,只能绑定dom元素。但是,如果我们自己写,我们可以随意绑定一个事件。命名,自己选择触发时机,写代码。首先,我们分析功能。我们需要一个观察者(这里抽象为一个对象{})。需要有一个属性,一个存储消息的盒子(把你绑定的所有事件都放在里面)需要一个on方法来添加事件需要一个emit方法来发布事件(触发)需要一个off方法来取消添加的方法constobserver={message:{},on:function(){},emit:function(){},off:function(){}}我们写成构造函数类Observer的形式{constructor(){this.message={}}on(){}emit(){}off(){}}现在,观察者的原型出来了。接下来,可以改进该方法。我们先写ON方法。添加一个事件我们的on方法需要接受两个参数EventtypeEventhandlerclassObserver{constructor(){this.message={}}on(type,fn){//判断消息框是否设置了事件类型if(!this.message[type]){//证明消息框里没有这个事件类型_//那我们直接加上_//并让它的值为数组,把事件处理函数放到this在数组中.message[type]=[fn]}else{//证明消息框里有这个事件类型_//那么我们可以直接在数组中添加事件处理函数_this.message[type].push(fn)}}emit(){}off(){}}EMIT下一步是发布事件。也就是说,让我们执行订阅的事件。它还需要接受两个参数。要触发的事件类型。传递给事件处理函数ParameterclassObserver{constructor(){this.message={}}on(type,fn){//判断消息框是否设置了事件类型if(!this.message[type]){//证明消息框里面没有这个事件类型_//那么我们直接添加_//并让它的值为一个数组,然后把事件处理函数放到数组中this.message[type]=[fn]}else{//证明消息框里有这个事件类型_//那么我们可以直接在数组中添加事件处理函数_this.message[type].push(fn)}}emit(type,...arg){//判断你之前是否订阅了这个事件if(!this.message[type])return//如果是,那么我们就处理参数constevent={type:type,参数:参数||{}}//循环执行是当前所有按事件类型订阅的事件处理程序this.message[type].forEach(item=>{item.call(this,event)})}off(){}}OFF最后是移除事件。它是删除订阅的事件处理程序。它还需要接受两个参数。待移除事件类型待移除事件处理器classObserver{constructor(){this.message={}}on(type,fn){//判断消息框是否设置了事件类型if(!this.message[type]){//证明消息框里没有这个事件类型_//那我们直接加上_//并让它的值为数组,然后把事件处理函数放上this.message[typeinthearray]=[fn]}else{//证明消息框里有这个事件类型_//那么我们可以直接在数组中添加事件处理函数_this.message[type]。push(fn)}}emit(type,...arg){//判断之前是否订阅过这个事件if(!this.message[type])return//如果是,那么我们处理参数const事件={类型:类型,arg:arg||{}}//循环所有订阅当前事件类型的事件处理器this.message[type].forEach(item=>{item.call(this,event)})}off(type,fn){//判断你之前是否订阅过这个事件if(!this.message[type])return//如果是,我们将移除它for(leti=0;i