资讯专栏INFORMATION COLUMN

JS之14种设计模式 (6)

luckyyulin / 1100人阅读

摘要:序列文章面试之函数面试之对象面试之数组的几个不操作面试之对比分析面试之数据结构与算法前言设计模式如果应用到项目中,可以实现代码的复用和解耦,提高代码质量。

序列文章

JS面试之函数(1)
JS面试之对象(2)
JS面试之数组的几个不low操作(3)
JS面试之http0.9~3.0对比分析(4)
JS面试之数据结构与算法 (5)

前言
设计模式如果应用到项目中,可以实现代码的复用和解耦,提高代码质量。 本文主要介绍14种设计模式
写UI组件,封装框架必备
1.简单工厂模式

1.定义:又叫静态工厂方法,就是创建对象,并赋予属性和方法
2.应用:抽取类相同的属性和方法封装到对象上
3.代码:

    let UserFactory = function (role) {
  function User(opt) {
    this.name = opt.name;
    this.viewPage = opt.viewPage;
  }
  switch (role) {
    case "superAdmin":
      return new User(superAdmin);
      break;
    case "admin":
      return new User(admin);
      break;
    case "user":
      return new User(user);
      break;
    default:
      throw new Error("参数错误, 可选参数:superAdmin、admin、user")
  }
}

//调用
let superAdmin = UserFactory("superAdmin");
let admin = UserFactory("admin") 
let normalUser = UserFactory("user")
//最后得到角色,可以调用
2.工厂方法模式

1.定义:对产品类的抽象使其创建业务主要负责用于创建多类产品的实例
2.应用:创建实例
3.代码:

var Factory=function(type,content){
  if(this instanceof Factory){
    var s=new this[type](content);
    return s;
  }else{
    return new Factory(type,content);
  }
}

//工厂原型中设置创建类型数据对象的属性
Factory.prototype={
  Java:function(content){
    console.log("Java值为",content);
  },
  PHP:function(content){
    console.log("PHP值为",content);
  },
  Python:function(content){
    console.log("Python值为",content);
  },
}

//测试用例
Factory("Python","我是Python");
3.原型模式

1.定义:设置函数的原型属性
2.应用:实现继承
3.代码:

function Animal (name) {
  // 属性
  this.name = name || "Animal";
  // 实例方法
  this.sleep = function(){
    console.log(this.name + "正在睡觉!");
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + "正在吃:" + food);
};

function Cat(){ 
}
Cat.prototype = new Animal();
Cat.prototype.name = "cat";

// Test Code
var cat = new Cat();
console.log(cat.name);//cat
console.log(cat.eat("fish"));//cat正在吃:fish  undefined
console.log(cat.sleep());//cat正在睡觉! undefined
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true  
4.单例模式

1.定义:只允许被实例化依次的类
2.应用:提供一个命名空间
3.代码:

let singleCase = function(name){
    this.name = name;
};
singleCase.prototype.getName = function(){
    return this.name;
}
// 获取实例对象
let getInstance = (function() {
    var instance = null;
    return function(name) {
        if(!instance) {//相当于一个一次性阀门,只能实例化一次
            instance = new singleCase(name);
        }
        return instance;
    }
})();
// 测试单体模式的实例,所以one===two
let one = getInstance("one");
let two = getInstance("two");   
5.外观模式

1.定义:为子系统中的一组接口提供一个一致的界面
2.应用:简化复杂接口
3.代码:
外观模式

6.适配器模式

1.定义:将一个接口转换成客户端需要的接口而不需要去修改客户端代码,使得不兼容的代码可以一起工作
2.应用:适配函数参数
3.代码:
适配器模式

7.装饰者模式

1.定义:不改变原对象的基础上,给对象添加属性或方法
2.代码

let decorator=function(input,fn){
  //获取事件源
  let input=document.getElementById(input);
  //若事件源已经绑定事件
  if(typeof input.onclick=="function"){
    //缓存事件源原有的回调函数
    let oldClickFn=input.onclick;
    //为事件源定义新事件
    input.onclick=function(){
      //事件源原有回调函数
      oldClickFn();
      //执行事件源新增回调函数
      fn();
    }
  }else{
    //未绑定绑定
    input.onclick=fn;
  }
}

//测试用例
decorator("textInp",function(){
  console.log("文本框执行啦");
})
decorator("btn",function(){
  console.log("按钮执行啦");
})
8.桥接模式

1.定义:将抽象部分与它的实现部分分离,使它们都可以独立地变化
2.代码
桥接模式

9.模块方法模式

1.定义:定义一个模板,供以后传不同参数调用
2.代码:
模块方法模式

10.观察者模式

1.作用:解决类与对象,对象与对象之间的耦合
2.代码:

let Observer=
  (function(){
    let _message={};
    return {
      //注册接口,
        //1.作用:将订阅者注册的消息推入到消息队列
        //2.参数:所以要传两个参数,消息类型和处理动作,
        //3.消息不存在重新创建,存在将消息推入到执行方法
        
      regist:function(type,fn){
        //如果消息不存在,创建
        if(typeof _message[type]==="undefined"){
          _message[type]=[fn];
        }else{
          //将消息推入到消息的执行动作
          _message[type].push(fn);
        }
      },

      //发布信息接口
        //1.作用:观察这发布消息将所有订阅的消息一次执行
        //2.参数:消息类型和动作执行传递参数
        //3.消息类型参数必须校验
      fire:function(type,args){
        //如果消息没有注册,则返回
        if(!_message[type]) return;
          //定义消息信息
          var events={
            type:type, //消息类型
            args:args||{} //消息携带数据
          },
          i=0,
          len=_message[type].length;
          //遍历消息
          for(;i=0;i--){
            //如果存在该动作在消息队列中移除
            _message[type][i]===fn&&_message[type].splice(i,1);
          }
        }
      }
    }
  })()

//测试用例
  //1.订阅消息
  Observer.regist("test",function(e){
    console.log(e.type,e.args.msg);
  })

  //2.发布消息
  Observer.fire("test",{msg:"传递参数1"});
  Observer.fire("test",{msg:"传递参数2"});
  Observer.fire("test",{msg:"传递参数3"});
11.状态模式

1.定义:一个对象状态改变会导致行为变化
2.作用:解决复杂的if判断
3.代码
状态模式

12.策略模式

1.定义:定义了一系列家族算法,并对每一种算法多带带封装起来,让算法之间可以相互替换,独立于使用算法的客户
2.代码
策略模式

13.访问模式

1.定义:通过继承封装一些该数据类型不具备的属性,
2.作用:让对象具备数组的操作方法
3.代码:
访问者模式

14.中介者模式

1.定义:设置一个中间层,处理对象之间的交互
2.代码:
中介者模式

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/103360.html

相关文章

  • JavaScript物理引擎Matter.js与Box2d性能对比

    摘要:数据采集因为是测试物理引擎的性能,这里不考虑,只采集物理引擎更新每一帧的时间,因为除开物理引擎,渲染引擎也会带来性能消耗。 前言 在挑选JavaScript 2D物理引擎的时候,不外乎两种主流的选择:第一种是老牌的Box2D,最开始的版本是C++实现的,后来有了很多种实现,比如flash版本和js版本,具体可看:https://stackoverflow.com/que...;第二种是...

    whinc 评论0 收藏0
  • JS数组的几个不low操作(3)

    摘要:序列文章面试之函数面试之对象前言本文主要从应用来讲数组的一些骚操作如一行代码扁平化维数组数组去重求数组最大值数组求和排序对象和数组的转化等上面这些应用场景你可以用一行代码实现扁平化维数组终极篇是扁平数组的表示维度值为时维度为无限大开始篇实质 showImg(https://segmentfault.com/img/bVbpRMS?w=1858&h=1286); 序列文章 JS面试之函数...

    fish 评论0 收藏0
  • JS 数组的几个经典api

    摘要:一扁平化嵌套数组展平和阵列孔实现效果方法删除数组中的空槽该方法创建一个新数组,所有子数组元素以递归方式连接到指定的深度。深度级别指定嵌套数组结构应该展平的深度。方法解读该方法的实质是利用递归和数组合并方法实现扁平。是将类数组转化为数组。 本文主要来讲数组api的一些操作,如简单实现扁平化n维数组、数组去重、求数组最大值、数组求和、排序、对象和数组的转化等。 一、 扁平化嵌套数组/展平和...

    陈江龙 评论0 收藏0
  • 温故知新JS基础

    摘要:访问属性是通过操作符完成的,但这要求属性名必须是一个有效的变量名小红的属性名不是一个有效的变量,就需要用括起来。闭包应用封装私有变量箭头函数箭头函数相当于匿名函数,并且简化了函数定义。 数据类型 NAN NaN === NaN; // false 唯一能判断NaN的方法是通过isNaN()函数: isNaN(NaN); // true 浮点数的相等比较: 1 / 3 === (...

    Dr_Noooo 评论0 收藏0

发表评论

0条评论

luckyyulin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<