经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » jQuery » 查看文章
js常用设计模式
来源:cnblogs  作者:new1one  时间:2019/5/13 8:56:48  对本文有异议

1.模块模式:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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.构造函数模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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.混合模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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.工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var Singleton = (function (){
  var instance;
  function init(){
    return {
      //
    };
  }
  return {
    getInstance: function(){
      if(!instance){
        instace = init();
      }
      return instance;
    }
  };
})();

6.发布-订阅模式:

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

发布-订阅模式广泛应用于异步编程之中,是一种替代回调函数的方案.多个事件处理函数可以订阅同一个事件,当该事件发生后,与其相对应的多个事件处理函数都会运行
取代对象之间硬编码的通知机制,一个对象不用再显示的调用另外一个对象的某个接口,降低模块之间的耦合程度,虽然不清楚彼此的细节,但是不影响他们之间相互通信
应用

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

自定义事件
指定发布者
"发布-订阅"这种关系用一个对象表示,键表示事件名,值是一个由事件处理程序组成的数组,相当于订阅者的花名册
发布消息后,遍历缓存列表,依次执行订阅者的回调函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
  }
})();

实际应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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.单体模式

  1. // 单体模式又称模块模式:用一个命名空间包含自己的所有代码的全局对象
  2. // 简单单体模式
  3. var timer = {
  4. seconds: 0,
  5. start: function () {
  6. setInterval(() => {
  7. this.seconds++
  8. }, 1000);
  9. },
  10. doFunc() {
  11. console.log('单体模式')
  12. }
  13. }
  14. setTimeout(() => {
  15. timer.doFunc()
  16. }, 3000);
  17. // 单体模式表现形式2
  18. var person = function personInfo(params) {
  19. this.name = 'name';
  20. this.getName = function () {
  21. // doSomeThing
  22. }
  23. this.method = function () {
  24. // doSomeThing
  25. }
  26. }
  27.  
  28. // 单体模式+闭包表现形式
  29. // 模块模式
  30. var DJtest = {}
  31. DJtest.common = function () {
  32. // doSomeThing
  33. }
  34. DJtest.init = function () {
  35. // doSomeThing
  36. }
  37. DJtest.func = function () {
  38. var val = 1
  39. function add1(str) {
  40. return parseInt(str) + val++
  41. }
  42. console.log(add1(1)) // 2
  43. return {
  44. sumAdd: function (str) {
  45. return add1(str)
  46. }
  47. }
  48. }()
  49. console.log(DJtest.func.sumAdd(1)) // 3
  50. console.log(DJtest.func.sumAdd(1)) // 4
  51. console.log(DJtest.func.sumAdd(1)) // 5

8.策略模式

  1. // 策略模式的定义是:定义一系列的算法/业务规则,把它们一个个封装起来,并且使它们可以相互替换。
  2.  
  3. // demo:根据级别计算奖金
  4. var calculateBouns = function(salary,level) {
  5. if(level === 'A') {
  6. return salary * 4;
  7. }
  8. if(level === 'B') {
  9. return salary * 3;
  10. }
  11. if(level === 'C') {
  12. return salary * 2;
  13. }
  14. };
  15.  
  16. console.log(calculateBouns(4000,'A')); // 16000
  17. console.log(calculateBouns(2500,'B')); // 7500
  18.  
  19. /**
  20. * describe:
  21. * 1,函数包含了很多if-else语句;
  22. * 2,函数缺乏弹性,扩展需要添加新的if,else;
  23. * 3,复用差
  24. * */
  25.  
  26. // 策略模式改造
  27. var obj = {
  28. "A": function (salary) {
  29. return salary * 4;
  30. },
  31. "B": function (salary) {
  32. return salary * 3;
  33. },
  34. "C": function (salary) {
  35. return salary * 2;
  36. }
  37. };
  38. var calculateBouns = function (level, salary) {
  39. return obj[level](salary);
  40. };
  41. console.log(calculateBouns('A',10000)); // 40000
  42.  
  43. // 优点:1. 策略模式利用组合,委托等技术和思想,有效的避免很多if条件语句。
  44. // 2. 策略模式提供了开放-封闭原则,使代码更容易理解和扩展。
  45. // 3. 策略模式中的代码可以复用。
  46. // tips:开放-封闭原则:对于扩展是开放的(Open for extension),对于更改是封闭的(Closed for modification)

 9.代理模式:参考链接

 

 

  

  

.

 

原文链接:http://www.cnblogs.com/wtfPro/p/10838565.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号