js常用设计模式

简介: js常用设计模式

1.模块模式:

在立即执行函数表达式中定义的变量和方法在外界是访问不到的,只能通过其向外部提供的接口,"有限制"地访问.通过函数作用域解决了属性和方法的封装问题.

var Person = (function(){

  var name = "xin";

  var age = 22;

  function getName(){

    return name;

  }

  function getAge(){

    return age;

  }

  return {

    getName: getName,

    getAge: getAge

  }

})();

 

console.log(age); // 报错:age未定义

console.log(name); // 报错:name未定义

console.log(Person.age); // undefined

console.log(Person.name); // undefined

// 只能通过Person提供的接口访问相应的变量

console.log(Person.getName()); // xin

console.log(Person.getAge()); // 22

2.构造函数模式

function Person(name,age){

  this.name = name;

  this.age = age;

}

Person.prototype = {

  constructor: Person;

  printName: function(){

    console.log(this.name);

  },

  printAge: function(){

    console.log(this.age);

  }

}

 

var person = new Person('xin', 22);

person.printName(); // xin

person.printAge(); // 22

3.混合模式

function Person(name,age){

  this.name = name;

  this.age = age;

};

Person.prototype.printName = function(){

  console.log(this.name);

}

function Student(name,age){

  // 继承 Person 的属性

  Person.call(this,name,age);

}

function create(prototype){

  function F(){};

  F.prototype = prototype;

  return new F();

}

 

// 让Student的原型指向一个对象,该对象的原型指向了Person.prototype,通过这种方式继承 Person 的方法

Student.prototype = create(Person.prototype);

Student.prototype.printAge = function(){

  console.log(this.age);

}

var student = new Student('xin',22);

student.printName(); // "xin"

4.工厂模式

function Person(name, age){

  var person = new Object();

  person.name = name;

  person.age = age;

  person.printName = function(){

    console.log(this.name);

  };

  person.printAge = function(){

    console.log(this.age);

  }

  return person;

}

 

var person = Person('xin',22);

5.单例模式

var Singleton = (function (){

  var instance;

  function init(){

    return {

      //

    };

  }

  return {

    getInstance: function(){

      if(!instance){

        instace = init();

      }

      return instance;

    }

  };

})();

6.发布-订阅模式:

发布-订阅模式又叫做观察者模式,定义了对象之间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖与它的对象都将得到通知.

发布-订阅模式广泛应用于异步编程之中,是一种替代回调函数的方案.多个事件处理函数可以订阅同一个事件,当该事件发生后,与其相对应的多个事件处理函数都会运行

取代对象之间硬编码的通知机制,一个对象不用再显示的调用另外一个对象的某个接口,降低模块之间的耦合程度,虽然不清楚彼此的细节,但是不影响他们之间相互通信

应用

DOM事件

DOM事件是一种典型的发布-订阅模式,对一个dom节点的一个事件进行监听,当操作dom节点时,触发相应的事件,响应函数执行.事件函数对dom节点完全未知,不用去理会是什么事件,如何触发,执行就好.

自定义事件

指定发布者

"发布-订阅"这种关系用一个对象表示,键表示事件名,值是一个由事件处理程序组成的数组,相当于订阅者的花名册

发布消息后,遍历缓存列表,依次执行订阅者的回调函数

var EventCenter = (function(){ 

  // 将所有的"发布-订阅"关系放到events中

  var events = {};

 

  /**

   * 给事件绑定事件处理程序

   * evt:事件名

   * handler:事件处理程序

   */

  function on(evt, handler){

    events[evt] = events[evt]||[];

    events[evt].push({

      handler:hander

    });

  }

 

  /**

   * 发布消息(触发事件),并执行相应的事件处理程序

   * evt:事件名

   * args:给事件处理程序传递的参数

   */

  function fire(evt,args){

    if(!events[evt]){

      return;

    }

    // 遍历事件处理程序列表,执行其中每一个事件处理程序

    for(var i=0;i<events[evt].length;i++){

      events[evt][i].handler(args);

    }

  }

 

  // 使用模块模式的方式,向外界提供绑定事件处理程序和触发事件的接口

  return {

    on: on,

    fire: fire

  }

})();

实际应用

var Event = (function(){ 

  var events = {};

 

  function on(evt, handler){

    events[evt] = events[evt]||[];

    events[evt].push({

      handler:handler

    });

  }

 

  function fire(evt,args){

    if(!events[evt]){

      return;

    }

 

    for(var i=0;i<events[evt].length;i++){

      events[evt][i].handler(args);

    }

  }

 

  function off(evt){

    delete events[evt];

  }

 

  return {

    on: on,

    fire: fire,

    off: off

  }

})();

Event.on('change'function(val){

  console.log('change...  now val is ' + val); 

});

Event.on('click'function(val){

  console.log('click.... now val is '+ val);

})

Event.fire('change''xin');

Event.fire('click''xin');

Event.off('change');

 

 

7.单体模式

 

// 单体模式又称模块模式:用一个命名空间包含自己的所有代码的全局对象
// 简单单体模式
var timer = {
seconds: 0,
start: function () {
setInterval(() => {
this.seconds++
}, 1000);
},
doFunc() {
console.log('单体模式')
}
}
setTimeout(() => {
timer.doFunc()
}, 3000);
 
// 单体模式表现形式2
var person = function personInfo(params) {
this.name = 'name';
this.getName = function () {
// doSomeThing
}
this.method = function () {
// doSomeThing
}
}
 
// 单体模式+闭包表现形式
// 模块模式
var DJtest = {}
DJtest.common = function () {
// doSomeThing
}
DJtest.init = function () {
// doSomeThing
}
DJtest.func = function () {
var val = 1
function add1(str) {
return parseInt(str) + val++
}
console.log(add1(1)) // 2
return {
sumAdd: function (str) {
return add1(str)
}
}
}()
console.log(DJtest.func.sumAdd(1)) // 3
console.log(DJtest.func.sumAdd(1)) // 4
console.log(DJtest.func.sumAdd(1)) // 5

8.策略模式

 

// 策略模式的定义是:定义一系列的算法/业务规则,把它们一个个封装起来,并且使它们可以相互替换。
 
// demo:根据级别计算奖金
var calculateBouns = function(salary,level) {
if(level === 'A') {
return salary * 4;
}
if(level === 'B') {
return salary * 3;
}
if(level === 'C') {
return salary * 2;
}
};
 
console.log(calculateBouns(4000,'A')); // 16000
console.log(calculateBouns(2500,'B')); // 7500
 
/**
* describe:
* 1,函数包含了很多if-else语句;
* 2,函数缺乏弹性,扩展需要添加新的if,else;
* 3,复用差
* */
 
// 策略模式改造
var obj = {
"A": function (salary) {
return salary * 4;
},
"B": function (salary) {
return salary * 3;
},
"C": function (salary) {
return salary * 2;
}
};
var calculateBouns = function (level, salary) {
return obj[level](salary);
};
console.log(calculateBouns('A',10000)); // 40000
 
// 优点:1. 策略模式利用组合,委托等技术和思想,有效的避免很多if条件语句。
// 2. 策略模式提供了开放-封闭原则,使代码更容易理解和扩展。
// 3. 策略模式中的代码可以复用。
// tips:开放-封闭原则:对于扩展是开放的(Open for extension),对于更改是封闭的(Closed for modification)
目录
相关文章
|
1月前
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
30 3
|
3月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
50 1
|
3月前
|
设计模式 JavaScript 前端开发
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
|
4月前
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
77 7
|
4月前
|
设计模式 JavaScript
js设计模式【详解】—— 桥接模式
js设计模式【详解】—— 桥接模式
67 6
|
4月前
|
设计模式 JavaScript
js设计模式【详解】—— 原型模式
js设计模式【详解】—— 原型模式
49 6
|
4月前
|
设计模式 JavaScript 前端开发
JavaScript进阶 - JavaScript设计模式
【7月更文挑战第7天】在软件工程中,设计模式是解决常见问题的标准解决方案。JavaScript中的工厂模式用于对象创建,但过度使用可能导致抽象过度和缺乏灵活性。单例模式确保唯一实例,但应注意避免全局状态和过度使用。观察者模式实现了一对多依赖,需警惕性能影响和循环依赖。通过理解模式的优缺点,能提升代码质量。例如,工厂模式通过`createShape`函数动态创建对象;单例模式用闭包保证唯一实例;观察者模式让主题对象通知多个观察者。设计模式的恰当运用能增强代码可维护性。
81 0
|
4月前
|
设计模式 缓存 JavaScript
js设计模式实例
【7月更文挑战第2天】JavaScript设计模式包含工厂、单例、建造者、抽象工厂和代理模式等,它们是最佳实践和可重用模板,解决创建、职责分配和通信等问题。例如,工厂模式封装对象创建,单例确保全局唯一实例,建造者模式用于复杂对象构建,抽象工厂创建相关对象集合,而代理模式则控制对象访问。这些模式提升代码质量、可读性和灵活性,是高效开发的关键。
37 0
|
6月前
|
设计模式 JavaScript 算法
js设计模式-策略模式与代理模式的应用
策略模式和代理模式是JavaScript常用设计模式。策略模式通过封装一系列算法,使它们可互换,让算法独立于客户端,提供灵活的选择。例如,定义不同计算策略并用Context类执行。代理模式则为对象提供代理以控制访问,常用于延迟加载或权限控制。如创建RealSubject和Proxy类,Proxy在调用RealSubject方法前可执行额外操作。这两种模式在复杂业务逻辑中发挥重要作用,根据需求选择合适模式解决问题。
|
设计模式 算法 JavaScript