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 相关文章推荐
Exjs 入门篇
Apr 07 Javascript
js 浏览器事件介绍
Mar 30 Javascript
jQuery瀑布流插件Wookmark使用实例
Apr 02 Javascript
javascript格式化指定日期对象的方法
Apr 21 Javascript
JavaScript自学笔记(必看篇)
Jun 23 Javascript
Angularjs实现带查找筛选功能的select下拉框示例代码
Oct 04 Javascript
Bootstrap企业网站实战项目4
Oct 14 Javascript
JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
Jan 05 Javascript
Angular.js实现多个checkbox只能选择一个的方法示例
Feb 24 Javascript
详解Vue中watch对象内属性的方法
Feb 01 Javascript
JavaScript实现图片上传并预览并提交ajax
Sep 30 Javascript
Vue前端项目部署IIS的实现
Jan 06 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下删除一篇文章生成的多个静态页面
2010/08/08 PHP
php产生随机数的两种方法实例代码 输出随机IP
2011/04/08 PHP
is_uploaded_file函数引发的不能上传文件问题
2013/10/29 PHP
php构造函数的继承方法
2015/02/09 PHP
PHP结合Vue实现滚动底部加载效果
2017/12/17 PHP
thinkphp5实现微信扫码支付
2019/12/23 PHP
Centos7安装swoole扩展操作示例
2020/03/26 PHP
JavaScript 拖拉缩放效果
2008/12/10 Javascript
javascript学习笔记(一)基础知识
2014/09/30 Javascript
深入浅出ES6新特性之函数默认参数和箭头函数
2016/08/01 Javascript
AngularJS自定义指令之复制指令实现方法
2017/05/18 Javascript
npm 更改默认全局路径以及国内镜像的方法
2018/05/16 Javascript
vue中各选项及钩子函数执行顺序详解
2018/08/25 Javascript
Vue结合后台导入导出Excel问题详解
2019/02/19 Javascript
ionic3双击返回退出应用的方法
2019/09/17 Javascript
js实现登录时记住密码的方法分析
2020/04/05 Javascript
Python算术运算符实例详解
2017/05/31 Python
python或C++读取指定文件夹下的所有图片
2019/08/31 Python
利用Tensorflow的队列多线程读取数据方式
2020/02/05 Python
Python3 mmap内存映射文件示例解析
2020/03/23 Python
Jmeter HTTPS接口测试证书导入过程图解
2020/07/22 Python
日本著名的服饰鞋帽综合类购物网站:MAGASEEK
2019/01/09 全球购物
西安当代医院管理研究院笔试题
2015/12/11 面试题
中专生学习生活的自我评价分享
2013/10/27 职场文书
养殖人员的创业计划书范文
2013/12/26 职场文书
春节联欢晚会主持词范文
2014/03/24 职场文书
期末评语大全
2014/05/04 职场文书
青春演讲稿范文
2014/05/08 职场文书
保护环境演讲稿
2014/05/10 职场文书
学生夜不归宿检讨书
2014/09/23 职场文书
法学专业大学生实习自我鉴定
2014/10/05 职场文书
普通党员个人整改措施
2014/10/27 职场文书
构建和谐校园倡议书
2015/01/19 职场文书
PyQt5 显示超清高分辨率图片的方法
2021/04/11 Python
Python中zipfile压缩包模块的使用
2021/05/14 Python
mysql left join快速转inner join的过程
2021/06/30 MySQL