设计模式
单例模式
import Single from './single.js'; { let zhangsan = new Single("张三"); let lisi = new Single("李四"); let wangwu = new Single("王五"); // console.log(zhangsan,lisi,wangwu); // console.log(zhangsan === lisi);//true // 实例化多少个依然还是一个,并且他们是相等的~ } { // console.log(Single("张三")); let zhangsan = new Single("张三"); let lisi = new Single("李四"); console.log(zhangsan,lisi) }
/* 单例模式: 保证只有一个实例(实例化),也就是只有一个对象,不管实例化多少次,我们都始终是只有一个实例 用处在哪些地方呢: 1.业务需求:比如只需要一个播放器,当我们点击的时候就会有多个播放器.所以就需要使用单例模式 2.性能:有些时候用多个实例和一个实例都是一样的情况下,可以考虑使用单例模式 缺点: 扩展性不强,对外比较封闭一些. */ /* export default class Person{ constructor(name){ this.name = name; } } */ /* // 使用类的静态属性 static -> 注意静态属性是属于类的属性! export default class Person{ static instance = null; constructor(name){ if(Person.instance){//如果有就走这里 return Person.instance;//return 代表下面代码也就不执行了 } Person.instance = this;//直接让它赋值为 实例化对象; this.name = name; } } 缺点: 在设计模式这块,一般情况下,对内是封闭的,对外是提供一些接口 当别人修改类的静态属性是,这个单例模式就失效了 Person.instance = null; 所以这样的安全性并不是很高不是很好 */ // 使用导出实例化对象 class Person{ constructor(name){ this.name = name; } } let instance = null; export default function(...arg){ if(!instance){ instance = new Person(...arg); } return instance; }
工厂模式
{ function Factory(name){ let o = {};//创建 // 添加 o.name = name; o.fn = function(){ console.log("...fn"); } // 返还 return o; } Factory(); } { // 生成英雄的工厂 class LuBan{ constructor(){ this.name = "鲁班七号"; } } class YaSe{ constructor(){ this.name = "亚瑟"; } } function Factory(heroName){ switch(heroName){ case "luban" : return new LuBan(); break; case "yase" : return new YaSe(); break; default: console.log("没有英雄"); break; } } let luban = Factory("luban"); console.log(luban); console.log( Factory("yase") ) }
装饰者模式
{ // 对对象进行 装饰 class Hero{ constructor(name){ this.name = name; } fire(){ console.log("释放技能"); } } /* 这时候若想扩展一些功能,且不想在原有的类里面改动,和继承差不多~ 装饰者模式和继承的一些区别 继承是可以添加一些方法 装饰者模式一般是在方法里面进行 扩展一些功能 一个是竖,一个是横 */ let fireDecoretor = function(hero){ this.hero = hero; } fireDecoretor.prototype.fire = function(){ this.hero.fire(); console.log("伤害100点"); } let luban = new Hero(); let newLuban = new fireDecoretor(luban); newLuban.fire();// 释放技能 伤害100点 } { // 装饰函数: 函数执行之前执行一些方法 Function.prototype.before = function(beforeFn,...arg){ beforeFn.call(this);//调用将要执行的方法 return this.call(this,...arg); } function fn(){ console.log("之前执行的函数"); console.log(this); } // 要执行的函数 function fireDecoretor(arg){ console.log("要执行的函数",arg); } // 调用方法的时候: fireDecoretor.before(fn,"参数"); }
观察者模式/自定义事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button class="btn">点击</button> </body> <script> function fn1(){ console.log("fn1...") }; // 这是时候若想扩展 逻辑可以使用 观察者模式 function fn2(){ console.log("fn2..."); } // fn1(); // fn2(); // 但是有很多很多的时候,... let handle = {}; addEvent("myEvent",fn1); addEvent("myEvent",fn2); removeEvent("myEvent",fn1); trigger("myEvent"); // document.querySelector(".btn").addEventListener("click",fn1); // document.querySelector(".btn").addEventListener("click",fn2); // 如何实现像系统事件 一样有一个绑定事件呢? // handle = { fn:[fn1,fn2],event:[fn1,fn2...] } // 添加自定义事件 function addEvent(eventName,fn){ if(typeof handle[eventName] === "undefined"){//代表没有这个数组 handle[eventName] = [];//那就创建数组 } handle[eventName].push(fn); } // 触发自定义事件 function trigger(eventName){ for(let i = 0;i<handle[eventName].length;i++){ handle[eventName][i](); } } // 移出自定义事件: 判断与删除; function removeEvent(eventName,fn){ for(let i = 0;i<handle[eventName].length;i++){ if(handle[eventName][i]===fn){ handle[eventName].splice(i,1); break; } } } </script> </html>
export default class GameEvent{ constructor(){ handle = {} } addEvent(eventName,fn){ if(typeof this.handle[eventName] === "undefined"){//代表没有这个数组 this.handle[eventName] = [];//那就创建数组 } this.handle[eventName].push(fn); } trigger(eventName){ for(let i = 0;i<this.handle[eventName].length;i++){ this.handle[eventName][i](); } } removeEvent(eventName,fn){ for(let i = 0;i<this.handle[eventName].length;i++){ if(this.handle[eventName][i]===fn){ this.handle[eventName].splice(i,1); break; } } } }
成功一定有方法,失败一定有原因

浙公网安备 33010602011771号