JavaScript原生实现观察者模式的示例


Posted in Javascript onDecember 15, 2017

观察者模式又叫做发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察着对象。 它是由两类对象组成,主题和观察者,主题负责发布事件,同时观察者通过订阅这些事件来观察该主体,发布者和订阅者是完全解耦的,彼此不知道对方的存在,两者仅仅共享一个自定义事件的名称。

在Nodejs中通过EventEmitter实现了原生的对于这一模式的支持。

在JavaScript中事件监听机制就可以理解为一种观察者模式。通过onclick进行事件绑定,然后通过交互行为进行触发或者事件主动触发。

下面给出一个JS自定义的PubSub,仔细阅读下面这段代码有助于你理解观察者模式。

一、定义观察者类Pubsub

/* Pubsub */
 function Pubsub(){
  //存放事件和对应的处理方法
 this.handles = {};
 }

二、实现事件订阅on

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

三、实现事件发布emit

emit: function () {
  //通过传入参数获取事件类型
 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];
   //执行事件
  handle.apply(this, arguments);
  }
 }

需要说明的是Array.prototype.shift.call(arguments)这句代码,arguments对象是function的内置对象,可以获取到调用该方法时传入的实参数组。

shift方法取出数组中的第一个参数,就是type类型。

四、实现事件取消订阅off

off: function (type, handle) {
  handles = this.handles[type];
  if(handles){
   if(!handle){
    handles.length = 0;//清空数组
  }else{
    for (var i = 0; i < handles.length; i++) {
     var _handle = handles[i];
     if(_handle === handle){
      handles.splice(i,1);
     }
    }
   }
  }
 }

完整代码:

/* Pubsub */
 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 () {
   //通过传入参数获取事件类型
  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];
    //执行事件
   handle.apply(this, arguments);
   }
  },
  off: function (type, handle) {
   handles = this.handles[type];
   if(handles){
    if(!handle){
     handles.length = 0;//清空数组
   }else{
 for (var i = 0; i < handles.length; i++) {
      var _handle = handles[i];
      if(_handle === handle){
       handles.splice(i,1);
      }
     }
    }
   }
  }
 }

五、测试

var p1 = new Pubsub();
 p1.on('mm', function (name) {
 console.log('mm: '+ name);
 });
 p1.emit('mm','哈哈哈哈');
console.log('===============');
 var p2 = new Pubsub();
 var fn = function (name) {
 console.log('mm2: '+ name);
 };
 var fn2 = function (name) {
 console.log('mm222: '+ name);
 };
 p2.on('mm2', fn);
 p2.on('mm2', fn2);
 p2.emit('mm2','哈2哈2哈2哈2');
 console.log('-------------');
p2.off('mm2', fn);
 p2.emit('mm2','哈2哈2哈2哈2');
 console.log('-------------');
p2.off('mm2');
 p2.emit('mm2','哈2哈2哈2哈2');
 console.log('-------------');

JavaScript原生实现观察者模式的示例

以上这篇JavaScript原生实现观察者模式的示例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
关于event.cancelBubble和event.stopPropagation()的区别介绍
Dec 11 Javascript
nullJavascript中创建对象的五种方法实例
May 07 Javascript
JS实现的数组全排列输出算法
Mar 19 Javascript
jquery序列化方法实例分析
Jun 10 Javascript
整理一下常见的IE错误
Nov 18 Javascript
JS对象的深度克隆方法示例
Mar 16 Javascript
Vue 2.0在IE11中打开项目页面空白的问题解决
Jul 16 Javascript
Vue 实现展开折叠效果的示例代码
Aug 27 Javascript
Vue CLI 3.x 自动部署项目至服务器的方法
Apr 02 Javascript
Node爬取大批量文件的方法示例
Jun 28 Javascript
Vue3.0中的monorepo管理模式的实现
Oct 14 Javascript
JavaScript canvas实现雨滴特效
Jan 10 Javascript
基于javascript 显式转换与隐式转换(详解)
Dec 15 #Javascript
ReactNative中使用Redux架构总结
Dec 15 #Javascript
Angular中使用MathJax遇到的一些问题
Dec 15 #Javascript
vue实现验证码输入框组件
Dec 14 #Javascript
基于滚动条位置判断的简单实例
Dec 14 #Javascript
微信小程序实现动态设置placeholder提示文字及按钮选中/取消状态的方法
Dec 14 #Javascript
ES6/JavaScript使用技巧分享
Dec 14 #Javascript
You might like
PHP 分页原理分析,大家可以看看
2009/12/21 PHP
基于asp+ajax和数据库驱动的二级联动菜单
2010/05/06 PHP
PHP中的integer类型使用分析
2010/07/27 PHP
浅谈php fopen下载远程文件的函数
2016/11/18 PHP
jQuery实现网页抖动的菜单抖动效果
2015/08/07 Javascript
ajax如何实现页面局部跳转与结果返回
2015/08/24 Javascript
jquery实现全选、反选、获得所有选中的checkbox
2020/09/13 Javascript
手机软键盘弹出时影响布局的解决方法
2016/12/15 Javascript
js鼠标经过tab选项卡时实现切换延迟
2017/03/24 Javascript
详解如何使用webpack打包Vue工程
2017/05/27 Javascript
vue 全选与反选的实现方法(无Bug 新手看过来)
2018/02/09 Javascript
vue 登录滑动验证实现代码
2018/08/24 Javascript
jqGrid表格底部汇总、合计行footerrow处理
2019/08/21 Javascript
layui使用button按钮 点击出现弹层 弹层中加载表单的实例
2019/09/04 Javascript
Vue混入mixins滚动触底的方法
2019/11/22 Javascript
[48:27]EG vs Liquid 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
Python MD5文件生成码
2009/01/12 Python
35个Python编程小技巧
2014/04/01 Python
python3.6使用pickle序列化class的方法
2018/10/22 Python
解决pycharm运行时interpreter为空的问题
2018/10/29 Python
python实现AES加密和解密
2019/03/27 Python
Python多版本开发环境管理工具介绍
2019/07/03 Python
详解Python并发编程之从性能角度来初探并发编程
2019/08/23 Python
logging level级别介绍
2020/02/21 Python
matplotlib subplot绘制多个子图的方法示例
2020/07/28 Python
CSS3 3D立方体效果示例-transform也不过如此
2016/12/05 HTML / CSS
windeln官方海外旗舰店:德淘超人气母婴超市
2017/12/15 全球购物
Paper Cape官网:美国婴儿和儿童服装品牌
2019/11/02 全球购物
主键(Primary Key)约束和唯一性(UNIQUE)约束的区别
2013/05/29 面试题
长辈证婚人证婚词
2014/01/09 职场文书
信息专业毕业生五年职业规划参考
2014/02/06 职场文书
大学班级干部的自我评价分享
2014/02/10 职场文书
幼儿园父亲节活动方案
2014/03/11 职场文书
在校学生证明格式
2015/06/24 职场文书
2016社区平安家庭事迹材料
2016/02/26 职场文书
导游词之任弼时故居
2020/01/07 职场文书