Js-设计模式分析

    技术2022-07-11  94

    Ⅰ- 壹 - 什么是设计模式 ?

    原生 js 中没有设计模式,它是模仿 java 语言中的设计模式来实现。

    设计模式分为三种类型,共23种。

    创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。

    Ⅱ - 贰 - 工厂模式

    工厂模式就是做一个对象创建的封装,并将创建的对象 return 出去。

    工厂模式适用于:

    当一个类不知道它所必须创建的对象的类的时候。当一个类希望由它的子类来指定它所创建的对象的时候。当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

    工厂模式普通写法:

    function CreateMan(name,age) { var obj={}; obj.name=name; obj.age=age; obj.sayName=function () { return this.name; }; return obj; } var p1=CreateMan("zhangsan",20); var p2=CreateMan("wangwu",30);

    工厂模式复杂写法,每一个类都应该是一个单独的文件:

    class CarFactory{ static get CAR(){ return "Car"; } static get BUS(){ return "Bus"; } static get TAXI(){ return "TAXI"; } static createCar(type){ switch(type){ case CarFactory.CAR: return new Car(); case CarFactory.BUS: return new Bus(); case CarFactory.TAXI: return new Taxi(); } } } class Car{ constructor(){ } getName(){ console.log("这是一个:"+this.constructor.name) } } class Bus extends Car{ constructor(){ super(); } } class Taxi extends Car{ constructor(){ super(); } } var car1=CarFactory.createCar(CarFactory.BUS); var car2=CarFactory.createCar(CarFactory.TAXI); car1.getName();//这是一个:Bus car2.getName();//这是一个:Taxi

    Ⅲ - 叁 - 单例模式

    单例模式就是运行完成后返回的对象是唯一的,如果已经创建出来就直接返回。 单例模式的普通写法:

    var obj; function getInstance(){ return obj || (obj={}); } var s=getInstance(); var o=getInstance(); console.log(s===o);//true

    单例模式的复杂写法:

    //使用闭包的形式,防止在外部更改 _instance 的值 let ViewModel=(function(){ var _instance; return class ViewModel{ constructor(){ } static getInstance(){ if(!_instance) _instance=new ViewModel(); return _instance; } } })(); var a=ViewModel.getInstance(); var b=ViewModel.getInstance(); console.log(a===b);//true

    Ⅳ - 肆 - 构造器模式

    构造器是一个当新建对象的内存被分配后,用来初始化该对象的一个特殊函数。对象构造器是被用来创建特殊类型的对象的,首先它要准备使用的对象,其次在对象初次被创建时,通过接收参数,构造器要用来对成员的属性和方法进行赋值。

    function CreateMan(name,age) { this.name=name; this.age=age; this.toString=function () { return this.name+"年龄:"+this.age; } } var p1=new CreateMan("zhangsan",20); var p2=new CreateMan("wangwu",30); console.log(p1.toString()); console.log(p2.toString());

    Ⅴ - 伍 - 桥接模式

    桥接模式可以理解为将抽象部分与它的实现部分分离,使它们都可以独立地变化。它的本质就是函数的封装,在实现api的时候,桥接模式非常常用。例如 some() 的实现过程,some函数并不关心 fn 里面的具体实现,fn 里面的逻辑也不会被 some 函数的改写影响。

    var list = [1,2,3,4,5]; function some(arr,fn){ for(var i=0;i<arr.length;i++){ //如果数组的元素是空,则跳过 if(arr[i]===undefined) continue; //如果fn()的返回结果是true,则返回true if(fn(arr[i],i,arr)) return true; } //默认返回false return false; } var s = some(list,function(item,index,arr){ return item>4 }) console.log(s);//true

    Ⅵ - 陆 - 外观模式

    外观模式是一种无处不在的模式,外观模式提供一个高层接口,这个接口使得客户端或者子系统调用起来更加方法。比如:这样就方便组装,如果一开始就把两个写到一个函数中,那就不能够只单独调用其中一个了。

    function getName() { return "xiaoming"; } function getSex() { return "man"; } function getUserInfo() { var info=getName()+getSex(); return info; } console.log(getUserInfo());

    Ⅶ - 柒 - 代理模式

    当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一些处理之后,再把请求转交给本体对象。代理和本体的接口具有一致性,本体定义了关键功能,而代理是提供或拒绝对它的访问,或者在访问本体之前做一些额外的事情。 代理模式主要有三种:

    保护代理,指拒绝访问主体;虚拟代理,在控制对主体进行访问时,加入了一些额外的操作;缓存代理,为一些数据大的运算结果提供暂时的缓存,提升效率(类似于闭包中的局部变量)。 // 主体,发送消息 function sendMsg(msg) { console.log(msg); } // 代理,对消息进行过滤 function proxySendMsg(msg) { // 无消息则直接返回,这是保护代理 if (typeof msg === "undefined") { return; } // 有消息则进行过滤,这是虚拟代理 msg = ("" + msg).replace(/小朋友/g, ''); sendMsg(msg); } sendMsg('你好小朋友'); //你好小朋友 proxySendMsg('你好小朋友'); //你好 proxySendMsg();

    Ⅷ - 捌 - 观察者模式

    定义对象间一种一对多的依赖关系,使得每当一个对象改变状态时,所有依赖于它的对象都会得到通知并被自动更新。通俗点理解,就是面试官是被观察者,而等待通知的人是观察者

    观察者模式的三个步骤:添加至观察列表,从观察列表中移除,进行观察。

    javascript中平时接触的dom事件,其实就是一种观察者模式的体现:

    div.onclick=function click(){ console.log("click" ) }

    0 - 0 - 知识点:

    Processed: 0.018, SQL: 9