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 相关文章推荐
jquery 必填项判断表单是否为空的方法
Sep 14 Javascript
javascript中的prototype属性使用说明(函数功能扩展)
Aug 16 Javascript
js 函数调用模式小结
Dec 26 Javascript
JavaScript中用sort()方法对数组元素进行排序的操作
Jun 09 Javascript
谈一谈javascript中继承的多种方式
Feb 19 Javascript
javascript html5 canvas实现可拖动省份的中国地图
Mar 11 Javascript
神奇!js+CSS+DIV实现文字颜色渐变效果
Mar 16 Javascript
js检查是否关闭浏览器的方法
Aug 02 Javascript
js捆绑TypeScript声明文件的方法教程
Apr 13 Javascript
vue中的$emit 与$on父子组件与兄弟组件的之间通信方式
May 13 Javascript
vue-cli脚手架搭建的项目去除eslint验证的方法
Sep 29 Javascript
js实现带箭头的进度流程
Mar 26 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
在DC的漫画和电影中,蝙蝠侠的宿敌,小丑的真名是什么?
2020/04/09 欧美动漫
十天学会php之第三天
2006/10/09 PHP
PHP parse_url 一个好用的函数
2009/10/03 PHP
关于使用key/value数据库redis和TTSERVER的心得体会
2013/06/28 PHP
WordPress中访客登陆实现邮件提醒的PHP脚本实例分享
2015/12/14 PHP
PHP实现表单提交时去除斜杠的方法
2016/12/26 PHP
PHP多个图片压缩成ZIP的方法
2020/08/18 PHP
JavaScript 空位补零实现代码
2010/02/26 Javascript
jquery随机展示头像代码
2011/12/21 Javascript
Javascript遍历Html Table示例(包括内容和属性值)
2014/07/08 Javascript
Js实现自定义右键行为
2015/03/26 Javascript
js实现基于正则表达式的轻量提示插件
2015/08/29 Javascript
jQuery的ajax和遍历数组json实例代码
2016/08/01 Javascript
javascript学习之json入门
2016/12/22 Javascript
jQuery表格(Table)基本操作实例分析
2017/03/10 Javascript
详解微信第三方小程序代开发
2017/06/23 Javascript
详解express与koa中间件模式对比
2017/08/07 Javascript
详解在React.js中使用PureComponent的重要性和使用方式
2018/07/10 Javascript
@angular前端项目代码优化之构建Api Tree的方法
2018/12/24 Javascript
在Create React App中使用CSS Modules的方法示例
2019/01/15 Javascript
jQuery实现表格的增、删、改操作示例
2019/01/27 jQuery
简述ES6新增关键字let与var的区别
2019/08/23 Javascript
利用numpy+matplotlib绘图的基本操作教程
2017/05/03 Python
Python探索之修改Python搜索路径
2017/10/25 Python
Python实现打印螺旋矩阵功能的方法
2017/11/21 Python
对python cv2批量灰度图片并保存的实例讲解
2018/11/09 Python
使用python批量修改文件名的方法(视频合并时)
2020/03/24 Python
django中使用POST方法获取POST数据
2019/08/20 Python
python list数据等间隔抽取并新建list存储的例子
2019/11/27 Python
Python使用requests模块爬取百度翻译
2020/08/25 Python
Forever 21美国官网:美国标志性快时尚品牌
2017/02/20 全球购物
巴西美妆购物网站:Kutiz Beauté
2019/03/13 全球购物
30岁生日感言
2014/01/25 职场文书
小城镇建设汇报材料
2014/08/16 职场文书
打架赔偿协议书范本
2014/10/26 职场文书
大学生党性分析材料
2014/12/19 职场文书