js设计模式(更新中)

链式调用
var methods=function () {}
Function.prototype.addMethods=function(name,fn){
  this[name]=fn;
  return this;
}
methods.addMethods('checkName',function () {
  console.log(111)
  return this;
}).addMethods('checkEmail',function () {
  console.log(222)
  return this;
})
methods.checkName().checkEmail()
var Methods=function () {}
Function.prototype.addMethods=function(name,fn){
  this.prototype[name]=fn;
  return this;
}
Methods.addMethods('checkName',function () {
  console.log(111)
  return this;
}).addMethods('checkEmail',function () {
  console.log(222)
  return this;
})

var m=new Methods();
m.checkName().checkEmail()
类式继承
//继承
function superClass() {
  this.superValue=true;
}
superClass.prototype.getSuperValue=function () {
  return this.superValue;
}

function subClass() {
  this.subValue=false;
}
//继承
subClass.prototype=new superClass();
subClass.prototype.getSubValue=function () {
  return this.subValue;
}
var m=new subClass();
console.log(m.getSuperValue());//true
console.log(m.getSubValue());//false

类式继承需要将第一个类的实例赋值给第二个类的原型

  • 类的原型对象的作用就是为类的原型添加共有方法,但类不能直接访问这些属性与方法,必须通过prototype访问
  • 当我们实例化一个父类时候,新创建的队形复制了父类构造函数内的属性与方法,并且将原型__proto__指向了弗雷德原型对象,这样就拥有了父类的原型对象的属性与方法,并且新创建的对象可以直接访问父类原型对象上的属性与方法。
  • 如果将新创建的对象赋值给子类的原型,子类的原型就能直接访问到父类的原型属性与方法。

通过以下方法可以检测某个对象是否属于某个类的实例,或者是否继承了耨个类:

var instance = new subClass();
console.log(instance instanceof subClass);//true
console.log(instance instanceof superClass);//true
console.log(subClass instanceof superClass);//false
简单工厂
//简单工厂
function createPop(type,text){
  var o=new Object();
  o.content=text;
  o.show=function (msg) {
    console.log(msg)
    //显示方法
  }
  if(type=='alert'){
    //警示框差异部分
    o.show(text);
  }
  if(type=='prompt'){
    //提示框差异部分
    o.show(text);
  }
  if(type=='confirm'){
    //确认框差异部分
    o.show(text);
  }
  return o;
}
var user=new createPop('alert','用户名只能是26个字母与数字');
安全模式工厂方法
var Factory=function (type,content) {
  if(this instanceof Factory){
    return new this[type](content)
  }
  else{
    return new Factory(type,content);
  }
}
Factory.prototype={
  java:function (content) {
    console.log(content)
  },
  php:function (content) {
    console.log(content)
  },
  ui:function (content) {
    console.log(content)
  }
}
Factory('java','java');
建造者模式

建造者模式关心的是建造的过程,通常需要将创造对象的类模块化,这样使得被创建的类的每一个模块都可以得到灵活的运用与高质量的复用,但缺点就是对整体对象类的拆分增加了结构的复杂性,因此如果模块间复用率很低并且变化不大,最好还是使用工厂模式

//建造者模式
var Human=function (param) {
  this.skill=param&&param.skill||'保密';
  this.hobby=param&&param.hobby||'保密';
}

Human.prototype={
  getSkill:function () {
    return this.skill;
  },
  getHobby:function () {
    return this.hobby;
  }
}

//实例化姓名
var Named=function (name) {
  var that=this;
  //构造器
  (function (name,that) {
    that.wholeName=name;
    if(name.indexOf(" ")>-1){
      that.firstMame=name.slice(0,name.indexOf(' '));
      that.secondName=name.slice(name.indexOf(" "));
    }
  })(name,that)
}

//实例化职位
var Work=function (work) {
  var that=this;
  (function (work,that) {
    switch(work){
      case 'code':
        that.work='工程师';
        that.workScript='每天沉醉于编程';
        break;
      case 'UI':
      case 'UE':
        that.work='设计师';
        that.workScript='设计更像一种艺术';
        break;
      case 'teach':
        that.work='教师';
        that.workScript='分享也是一种快乐';
        break;
      default:
        that.work=work;
        that.workScript='对不起,我们还不清楚你的职位描述';
    }
  })(work,that)
}
Work.prototype.changeWork=function (work) {
  this.work=work;
}
Work.prototype.changeScript=function (workScript) {
  this.workScript=workScript;
}

var Person=function (param={},name,work) {
  var _person=new Human(param);
  _person.name=new Named(name);
  _person.work=new Work(work);
  return _person;
}

var person=new Person({skill:'计算机',hobby:'爱好'},'xiao ming','code');
console.log(person.skill);//计算机
console.log(person.name.firstMame);//xiao
console.log(person.work.work);//工程师
console.log(person.work.workScript);//每天沉醉于编程
person.work.changeScript('更改一下职位描述!');
console.log(person.work.workScript);//更改一下职位描述!
原型模式
function loopImages(imgArr,container) {
  this.imgArr=imgArr;
  this.container=container;
}
loopImages.prototype.getImageLength=function () {
  return this.imgArr.length;
}
单例模式

它又称为单体模式,只允许实例化一次的对象类,有时用一个对象来规划一个命名空间,管理对象上属性与方法。

var A={
  Util:{
    util_method1:function () {
      console.log('util_method1');
    },
    util_method2:function () {
      console.log('util_method2');
    }
  },
  Tool:{
    tool_method1:function () {},
    tool_method2:function () {}
  },
  Ajax:{
    get:function () {},
    post:function () {}
  }
}
外观模式

外观模式为一组复杂的子系统提供一个更高级的统一接口。

function addEvent(dom,type,fn) {
  if(dom.addEventListener){
    dom.addEventListener(type,fn,false)
  }
  else if(dom.attachEvent){
    dom.attachEvent('on'+type,fn);
  }
  else{
    dom['on'+type]=fn;
  }
}
适配器模式

将一个接口转换成客户端需要的接口而不需要去修改客户端代码,使得不兼容的代码可以一起工作。
适配器主要有3个角色组成:
(1)客户端:调用接口的类
(2)适配器:用来连接客户端接口和提供服务的接口的类
(3)适配者:提供服务,但是却与客户端接口需求不兼容服务类。


代理模式
装饰者模式
  • 没有改变原有的构造函数对象,而是原封不动地拿过来,再添加新的方法。
  • 在不改变原对象的基础上,通过对其进行包装扩展(添加属性或方法),使原有对象可以满足用户的更复杂需求,满足开闭原则,也不会破坏现有的操作。
function Person() {}
Person.prototype.sayHello=function () {
  console.log('hello')
}
function Decorator(param) {
  this.person=param;
}
Decorator.prototype.sayHello=function () {
  this.person.sayHello()
  console.log('hello,everyone');
}
Decorator.prototype.sayGoodbye = function() {
  console.log('Bye, everyone!');
};
new Decorator(new Person()).sayHello();
new Decorator(new Person()).sayGoodbye();
var decorator=function (input,fn) {
  var input=document.getElementById(input);
  console.log(typeof input.onclick)
  if(typeof input.onclick==='function'){
    console.log(1)
    var oldFn=input.onclick;
    input.onclick=function () {
      oldFn();
      fn();
    }
  }
  else{
    console.log(0)
    input.onclick=fn;
  }
}
decorator('btn1',function () {
  document.getElementById('btn1').innerText='0'
})
decorator('btn1',function () {
  document.getElementById('btn1').innerText='1'
})
decorator('btn2',function () {
  document.getElementById('btn2').innerText='2'
})
decorator('btn3',function () {
  document.getElementById('btn3').innerText='3'
})
观察者模式
function Pubsub(){
  this.handles={};
}

Pubsub.prototype={
  //传入事件类型type和事件处理handle
  on:function (type,handle) {
    if(!this.handles[type]){
      this.handles[type]=[];
    }
    this.handles[type].push(handle)
  },

  //通过传入参数获取事件类型
  emit:function () {
    //["nyy", "hhh", callee: ƒ, Symbol(Symbol.iterator): ƒ] arguments值
    var type=Array.prototype.shift.call(arguments);
    if(!this.handles[type]){
      return false;
    }
    for(var i=0;i<this.handles[type].length;i++){
      var handle=this.handles[type][i];
      //执行事件
      //arguments ["hhh", callee: ƒ, Symbol(Symbol.iterator): ƒ]
      handle.apply(this,arguments);
    }
  },

  //取消事件
  off:function (type,handle) {
    var fns = this.handles[type];
    if(fns){
      if(!handle){
        fns.length=0;
      }else{
        for(var i=0;i<fns.length;i++){
          if(fns[i]==handle){
            fns.splice(i,1)
          }
        }
      }
    }
  }
}
var p1 = new Pubsub();
p1.on('nyy',function (name) {
  console.log(name)
})
p1.emit('nyy','hhh');
p1.emit('nyy','lxf');
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值