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 相关文章推荐
通过Unicode转义序列来加密,按你说的可以算是混淆吧
May 06 Javascript
Fixie.js 自动填充内容的插件
Jun 28 Javascript
append和appendTo的区别以及appendChild用法
Dec 24 Javascript
告诉你什么是javascript的回调函数
Sep 04 Javascript
JavaScript中的类数组对象介绍
Dec 30 Javascript
jQuery插件MixItUp实现动画过滤和排序
Apr 12 Javascript
JavaScript实现图片DIV竖向滑动的方法
Apr 25 Javascript
jQuery实现文件上传进度条特效
Aug 12 Javascript
vue富文本框(插入文本、图片、视频)的使用及问题小结
Aug 17 Javascript
Vue动态组件与异步组件实例详解
Feb 23 Javascript
JavaScript怎样在删除前添加确认弹出框?
May 27 Javascript
Vue快速实现通用表单验证功能
Dec 05 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+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
2007/02/15 PHP
PHPLog php 程序调试追踪工具
2009/09/09 PHP
PHP与C#分别格式化文件大小的代码
2011/05/14 PHP
使用php实现网站验证码功能【推荐】
2017/02/09 PHP
PHP文字转图片功能原理与实现方法分析
2017/08/31 PHP
YII框架页面缓存操作示例
2019/04/29 PHP
Prototype使用指南之string.js
2007/01/10 Javascript
Javascript+XMLHttpRequest+asp.net无刷新读取数据库数据
2009/08/09 Javascript
推荐20家国外的脚本下载网站
2011/04/28 Javascript
javascript利用控件对windows的操作实现原理与应用
2012/12/23 Javascript
node.js中的fs.fchownSync方法使用说明
2014/12/16 Javascript
js实现字符串转日期格式的方法
2015/05/20 Javascript
jQuery生成假加载动画效果
2016/12/01 Javascript
Bootstrap table使用方法详细介绍
2016/12/09 Javascript
input输入框内容实时监测(附代码)
2017/08/15 Javascript
浅析JavaScript中的特殊数据类型
2017/12/15 Javascript
利用vue.js把静态json绑定bootstrap的table方法
2018/08/28 Javascript
js尾调用优化的实现
2019/05/23 Javascript
JavaScript HTML DOM 元素 (节点)新增,编辑,删除操作实例分析
2020/03/02 Javascript
pymongo实现控制mongodb中数字字段做加法的方法
2015/03/26 Python
10种检测Python程序运行时间、CPU和内存占用的方法
2015/04/01 Python
python3.4用函数操作mysql5.7数据库
2017/06/23 Python
python 2.7 检测一个网页是否能正常访问的方法
2018/12/26 Python
Python Django基础二之URL路由系统
2019/07/18 Python
Django 路由层URLconf的实现
2019/12/30 Python
解决tensorflow训练时内存持续增加并占满的问题
2020/01/19 Python
基于Python3.7.1无法导入Numpy的解决方式
2020/03/09 Python
文件上传服务器-jupyter 中python解压及压缩方式
2020/04/22 Python
简述python Scrapy框架
2020/08/17 Python
比利时家具购买网站:Home24
2019/01/03 全球购物
有个性的自我评价范文
2013/11/15 职场文书
2014年小学植树节活动方案
2014/03/02 职场文书
学校欢迎标语
2014/06/18 职场文书
安全责任书
2015/01/29 职场文书
月考总结与反思
2015/10/22 职场文书
MySQL数据库配置信息查看与修改方法详解
2022/06/25 MySQL