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之dhDataGrid Ver2.0.0代码
Jul 01 Javascript
JavaScript 变量基础知识
Nov 07 Javascript
DIV外区域Click后关闭DIV的实现代码
Dec 21 Javascript
浅析Javascript使用include/require
Nov 13 Javascript
jquery获取css中的选择器(实例讲解)
Dec 02 Javascript
利用jquery动画特效和css打造的侧边弹出垂直导航
Apr 04 Javascript
JavaScript DOM基础
Apr 13 Javascript
jQuery检测某个元素是否存在代码分享
Jul 09 Javascript
基于angular实现模拟微信小程序swiper组件
Jun 11 Javascript
Javascript(es2016) import和require用法和区别详解
Aug 11 Javascript
ES6 javascript中Class类继承用法实例详解
Oct 30 Javascript
详解node.js 事件循环
Jul 22 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
也谈截取首页新闻 - 范例
2006/10/09 PHP
PHP编码规范之注释和文件结构说明
2010/07/09 PHP
Smarty模板简单配置与使用方法示例
2016/05/23 PHP
php获取网站根目录物理路径的几种方法(推荐)
2017/03/04 PHP
判断用户的在线状态 onbeforeunload事件
2011/03/05 Javascript
jQuery插件scroll实现无缝滚动效果
2015/04/27 Javascript
jquery实现用户信息修改验证输入方法汇总
2015/07/18 Javascript
javascript发送短信验证码实现代码
2015/11/12 Javascript
Bootstrap弹出框(modal)垂直居中的问题及解决方案详解
2016/06/12 Javascript
JS实现动态表格的添加,修改,删除功能(推荐)
2016/06/15 Javascript
利用Angularjs和原生JS分别实现动态效果的输入框
2016/09/01 Javascript
网站发布后Bootstrap框架引用woff字体无法正常显示的解决方法
2016/11/24 Javascript
使用base64对图片的二进制进行编码并用ajax进行显示
2017/01/03 Javascript
JavaScript类的继承方法小结【组合继承分析】
2018/07/11 Javascript
element UI upload组件上传附件格式限制方法
2018/09/04 Javascript
js new Date()实例测试
2019/10/31 Javascript
解决vue项目打包上服务器显示404错误,本地没出错的问题
2020/11/03 Javascript
python使用xmlrpc实例讲解
2013/12/17 Python
Python的Django框架中模板碎片缓存简介
2015/07/24 Python
使用Py2Exe for Python3创建自己的exe程序示例
2018/10/31 Python
Python+OpenCV实现图像融合的原理及代码
2018/12/03 Python
Python 随机按键模拟2小时
2020/12/30 Python
医药营销专业个人自荐信
2013/09/29 职场文书
教育专业自荐书范文
2013/12/17 职场文书
致长跑运动员广播稿
2014/01/31 职场文书
护士毕业实习感言
2014/03/05 职场文书
三分钟演讲稿范文
2014/04/24 职场文书
班组建设经验交流材料
2014/05/12 职场文书
企业党员一句话承诺
2014/05/30 职场文书
小学教师2014年度工作总结
2014/12/03 职场文书
2015年社区国庆节活动总结
2015/07/30 职场文书
资产移交协议书
2016/03/24 职场文书
导游词之平津战役纪念馆
2019/11/04 职场文书
解决linux下redis数据库overcommit_memory问题
2022/02/24 Redis
MySQL脏读,幻读和不可重复读
2022/05/11 MySQL
winserver2019安装软件一直卡在应用程序正在为首次使用做准备
2022/06/10 Servers