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 DOM 学习第七章 表单的扩展
Feb 19 Javascript
jQuery 图片切换插件(代码比较少)
May 07 Javascript
javascript 构造函数强制调用经验总结
Dec 02 Javascript
JQueryEasyUI datagrid框架的进阶使用
Apr 08 Javascript
JavaScript中for..in循环陷阱介绍
Nov 12 Javascript
js实现div层缓慢收缩与展开的方法
May 11 Javascript
JavaScript中实现map功能代码分享
Jun 11 Javascript
JS实现简单的图书馆享元模式实例
Jun 30 Javascript
原生JS实现获取及修改CSS样式的方法
Sep 04 Javascript
node.js使用redis储存session的方法
Sep 26 Javascript
JavaScript enum枚举类型定义及使用方法
May 15 Javascript
vue动画—通过钩子函数实现半场动画操作
Aug 09 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
global.php
2006/12/09 PHP
兼容PHP和Java的des加密解密代码分享
2014/06/26 PHP
php源码分析之DZX1.5加密解密函数authcode用法
2015/06/17 PHP
详解HTTP Cookie状态管理机制
2016/01/14 PHP
ThinkPHP中create()方法自动验证表单信息
2017/04/28 PHP
PHP正则验证字符串是否为数字的两种方法并附常用正则
2019/02/27 PHP
js实现简单模态窗口,背景灰显
2008/11/14 Javascript
JavaScript实现快速排序的方法
2015/07/31 Javascript
js获取图片宽高的方法
2015/11/25 Javascript
整理AngularJS框架使用过程当中的一些性能优化要点
2016/03/05 Javascript
实例详解jQuery的无new构建
2016/08/02 Javascript
AngularJS 服务详细讲解及示例代码
2016/08/17 Javascript
jQuery的 $.ajax防止重复提交的两种方法(推荐)
2016/10/14 Javascript
javascript笔记之匿名函数和闭包
2017/02/06 Javascript
React中jquery引用的实现方法
2017/09/12 jQuery
一文了解Vue中的nextTick
2019/05/06 Javascript
JS实现页面侧边栏效果探究
2021/01/08 Javascript
Python下的twisted框架入门指引
2015/04/15 Python
Windows下Anaconda2安装NLTK教程
2018/09/19 Python
python自动化unittest yaml使用过程解析
2020/02/03 Python
通过python 执行 nohup 不生效的解决
2020/04/16 Python
Python实现初始化不同的变量类型为空值
2020/06/02 Python
Python数据分析库pandas高级接口dt的使用详解
2020/12/11 Python
基于CSS3实现的黑色个性导航菜单效果
2015/09/14 HTML / CSS
介绍下static、final、abstract区别
2015/01/30 面试题
师范生实习自我鉴定
2013/11/01 职场文书
应届行政管理专业个人自我评价
2013/12/28 职场文书
如何写一份好的自荐信
2014/01/02 职场文书
教师年度考核自我鉴定
2014/01/19 职场文书
超市采购员岗位职责
2014/02/01 职场文书
后勤部经理岗位职责
2014/02/23 职场文书
目标责任书范本
2014/04/16 职场文书
幼儿园小班评语
2014/04/18 职场文书
我是一名护士演讲稿
2014/08/28 职场文书
2014矛盾纠纷排查调处工作总结
2014/12/09 职场文书
七年级作文之秋游
2019/10/21 职场文书