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 相关文章推荐
javascript 获取所有id中包含某关键字的控件的实现代码
Nov 25 Javascript
javascript之querySelector和querySelectorAll使用说明
Oct 09 Javascript
变量声明时命名与变量作为对象属性时命名的区别解析
Dec 06 Javascript
jquery dialog open后,服务器端控件失效的快速解决方法
Dec 19 Javascript
Windows 系统下安装和部署Egret的开发环境
Jul 31 Javascript
JS实现先显示大图后自动收起显示小图的广告代码
Sep 04 Javascript
关于input全选反选恶心的异常情况
Jul 24 Javascript
浅谈react 同构之样式直出
Nov 07 Javascript
详解React项目的服务端渲染改造(koa2+webpack3.11)
Mar 19 Javascript
微信小程序左右滚动公告栏效果代码实例
Sep 16 Javascript
jQuery实现图片随机切换、抽奖功能(实例代码)
Oct 23 jQuery
Vue-Ant Design Vue-普通及自定义校验实例
Oct 24 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 echo,print,printf,sprintf函数之间的区别与用法详解
2013/11/27 PHP
一个显示效果非常不错的PHP错误、异常处理类
2014/03/21 PHP
PHP中COOKIES使用示例
2015/07/26 PHP
laravel5.1框架model类查询的实现方法
2019/10/08 PHP
PHP设计模式入门之状态模式原理与实现方法分析
2020/04/26 PHP
Jquery UI震动效果实现原理及步骤
2013/02/04 Javascript
jquery 元素控制(追加元素/追加内容)介绍及应用
2013/04/21 Javascript
Javascript和HTML5利用canvas构建Web五子棋游戏实现算法
2013/07/17 Javascript
javascript查找字符串中出现最多的字符和次数的小例子
2013/10/29 Javascript
ie8模式下click无反应点击option无反应的解决方法
2014/10/11 Javascript
AngularJS中的模块详解
2015/01/29 Javascript
jQuery中prepend()方法使用详解
2015/08/11 Javascript
javascript的replace方法结合正则使用实例总结
2016/06/16 Javascript
jquery.Jcrop结合JAVA后台实现图片裁剪上传实例
2016/11/05 Javascript
微信小程序 textarea 组件详解及简单实例
2017/01/10 Javascript
利用Vue v-model实现一个自定义的表单组件
2017/04/27 Javascript
AngularJS实用基础知识_入门必备篇(推荐)
2017/07/10 Javascript
vue-cli配置文件——config篇
2018/01/04 Javascript
基于vue中keep-alive缓存问题的解决方法
2018/09/21 Javascript
详解vue-router 动态路由下子页面多页共活的解决方案
2019/12/22 Javascript
利用PHP实现递归删除链表元素的方法示例
2020/10/23 Javascript
[02:32]“虐狗”镜头慎点 2016国际邀请赛中国区预选赛现场玩家采访
2016/06/28 DOTA
Python的类实例属性访问规则探讨
2015/01/30 Python
python实现根据用户输入从电影网站获取影片信息的方法
2015/04/07 Python
用Python给文本创立向量空间模型的教程
2015/04/23 Python
进一步探究Python的装饰器的运用
2015/05/05 Python
深入理解Django的中间件middleware
2018/03/14 Python
django1.11.1 models 数据库同步方法
2018/05/30 Python
python print输出延时,让其立刻输出的方法
2019/01/07 Python
Python pickle模块常用方法代码实例
2020/10/10 Python
毕业生的自我评价范文
2013/12/31 职场文书
企业精细化管理实施方案
2014/03/23 职场文书
房屋鉴定委托书范本
2014/09/23 职场文书
2014年志愿者工作总结
2014/11/20 职场文书
标枪加油稿
2015/07/22 职场文书
go语言中切片与内存复制 memcpy 的实现操作
2021/04/27 Golang