轻松掌握:JavaScript观察者模式
观察者模式
观察者模式也叫“订阅者/发布者”模式,定义对象间的一种一对多的依赖关系,发布者可以向所有订阅者发布消息。
观察者模式被广泛地应用于JavaScript客户端编程中。所有的浏览器事件(mouseover,keypress等)都是使用观察者模式的例子。
使用这个模式的最主要目的就是促进对象之间的解耦(弱化对象之间的联系)。在观察者模式中,一组对象订阅另一个对象的指定活动并得到通知。
如:
document.body.addEventListener('click',function(){
alert(2);
},false);
以上代码订阅了document.body的click事件,当body被点击时,body便会向订阅者发布消息;
实现观察者模式的一般步骤:
- 先指定谁充当发布者;
- 给发布者添加一个缓存列表,用于存放回调函数以便通知订阅者;
- 发布消息时,发布者会遍历这个缓存列表,依次触发里面存放的订阅者回调函数;还可在回调函数内加入一些参数;
(也可先发布消息,将消息保存起来,当有订阅者时就将该消息重新发布给他)
发布-订阅模式的通用实现:
var Publisher = (function(){
//listenerList用来保存一系列的key,每个key为保存了所有订阅者函数fn的数组{ keyA:[fn1,fn2...], keyB:[...]...}
//类似:可以为同一事件注册多个回调函数
var listenerList = {};
return {
addListener: function(key,fn){
if(!listenerList[key]){
listenerList[key] = [];
}
if(listenerList[key].indexOf(fn) === -1){ //检测fn是否已订阅,注意indexOf方法不支持IE9以下,可用for循环代替
listenerList[key].push(fn);
}
},
publish: function(){
var key = Array.prototype.shift.call(arguments),
fns = listenerList[key];
if(!fns||fns.length === 0){
return false;
}
for(var i = 0,fn;fn = fns[i++];){
fn.apply(this,arguments);
}
},
removeListener: function(key,fn){
var fns = listenerList[key];
if(!fns){
return false;
}
if(!fn){ //若没指定fn,则表示取消所有订阅
fns && (fns.length = 0);
}else{ //可直接用fns.splice(listenerList[key].indexOf(fn),1);但indexOf方法不支持IE9以下
for(var l = fns.length - 1; l >= 0; l--){
if(fns[l] === fn){
fns.splice(l,1);
}
}
}
}
};
})();
Publisher.addListener('month',function(num){ //订阅month
console.log('本月数量: '+num);
});
Publisher.addListener('month',function(price){
console.log('本月价格: '+price);
});
Publisher.addListener('week',function(num){
console.log('本周数量: '+num);
});
Publisher.publish('month',123); //手动发布消息
//本月数量: 123
//本月价格: 123
Publisher.publish('week',5);
//本周数量: 5
实际应用:
$.ajax('http://xxx.com?login',function(data){
Publisher.publish('loginSuccess',data); //若登录成功则向所有订阅者发布登录成功的消息
});
//以下在各个模块添加订阅消息
var header = (function () {
Publisher.addListener('loginSuccess', function (data) {
header.setAvatar(data.avatar);
});
return {
setAvatar: function (data) {
console.log('设置header模块的头像')
}
}
})();
var nav = (function () {
Publisher.addListener('loginSuccess', function (data) {
nav.setAvatar(data.avatar);
});
return {
setAvatar: function (avatar) {
console.log('设置header模块的头像')
}
}
})();
//...可随意添加其他模块
参考文献:
《JavaScript模式》
《JavaScript设计模式与开发实践》
轻松掌握:JavaScript观察者模式的更多相关文章
- 轻松学习 JavaScript——第 6 部分:JavaScript 箭头函数
JavaScript箭头函数是ECMAScript 6中引入的编写函数表达式的一种简便方法.通常,在JavaScript中,可以通过两种方式创建函数: 函数语句. 函数表达式. 可以如下所示创建函数语 ...
- 轻松学习JavaScript十八:DOM编程学习之DOM简单介绍
一DOM概述 DOM(文档对象模型)是HTML和XML的应用程序接口(API).DOM将把整个页面规划成由节点层级构成的文档. DOM描绘了一个层次化的节点树,执行开发者加入,移除和改动页面的某一部分 ...
- 轻松理解JavaScript闭包
摘要 闭包机制是JavaScript的重点和难点,本文希望能帮助大家轻松的学习闭包 一.什么是闭包? 闭包就是可以访问另一个函数作用域中变量的函数. 下面列举出常见的闭包实现方式,以例子讲解闭包概念 ...
- 轻松理解JavaScript之AJAX
摘要 AJAX技术是网页构建的必备技能之一,本文希望能帮助大家轻松的学习这项技术 一.什么是ajax? ajax(异步javascript xml) 能够刷新局部网页数据而不是重新加载整个网页. 二. ...
- 分针网—每日分享: 怎么轻松学习JavaScript
js给初学者的印象总是那么的"杂而乱",相信很多初学者都在找轻松学习js的途径. 我试着总结自己学习多年js的经验,希望能给后来的学习者探索出一条"轻松学习js之路& ...
- JavaScript观察者模式
观察者模式观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得 ...
- 怎么轻松学习JavaScript
js给初学者的印象总是那么的“杂而乱”,相信很多初学者都在找轻松学习js的途径.我试着总结自己学习多年js的经验,希望能给后来的学习者探索出一条“轻松学习js之路”.js给人那种感觉的原因多半是因为它 ...
- 理解javascript观察者模式(订阅者与发布者)
什么是观察者模式? 观察者模式又叫做发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察着对象.它是由两类对象组成,主题和观察者 ...
- Javascript观察者模式(Object.defineProperty、Reflect和Proxy实现)
什么是观察者模式? 答:在数据发生改变时,对应的处理函数自动执行.函数自动观察数据对象,一旦对象有变化,函数就会自动执行. 参考<原生JavaScript实现观察者模式>(https:// ...
随机推荐
- Security6:授予权限的思路和一般步骤
思路是:Grants permissions on a securable to a principal. The general concept is to GRANT <some permi ...
- Hammer.js手势库 安卓4.0.4上的问题
Hammer.JS - v1.0.7dev - 2014-02-18 1.Hammer.JS 在安卓4.0.4 , 4.1上 touchmove事件丢失 https://code.google.com ...
- Java之控制反转和依赖注入
1.简介 依赖注入和控制反转,目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性,下面通过一个例子来引入这一概念. 2.案例 1)一般情况下的类耦合 Main.java public clas ...
- OpenCASCADE View Manipulator
OpenCASCADE View Manipulator eryar@163.com Abstract. When you finish modeling objects in the scene, ...
- herbnate session.createSQLQuery(sql) 和 session.createQuery(sql)使用
public class DistributeDao implements Serializable{ private SessionFactory sessionFactory; public Se ...
- MVC实用架构设计(三)——EF-Code First(5):二级缓存
前言 今天我们来谈谈EF的缓存问题. 缓存对于一个系统来说至关重要,但是是EF到版本6了仍然没有见到有支持查询结果缓存机制的迹象.EF4开始会把查询语句编译成存储过程缓存在Sql Server中,据说 ...
- Objective-C中的单例模式
单例模式算是设计模式中比较简单的一种吧,设计模式不是只针对某种编程语言,在C++, Java, PHP等其他OOP语言也有设计模式,笔者初接触设计模式是通过<漫谈设计模式>了解 ...
- RESTful API URI 设计: 查询(Query)和标识(Identify)
相关文章:RESTful API URI 设计的一些总结. 问题场景:删除一个资源(Resources),URI 该如何设计? 应用示例:删除名称为 iPhone 6 的产品. 是不是感觉很简单呢?根 ...
- 记录下帮助一位网友解决的关于android子控件的onTouch或onClick和父OnTouch 冲突的问题。
前三天收到位网友的私信求助,问题大概如标题所示.具体是下面的情况,个人感觉,这个问题挺有趣,也会在实际项目开发中很常见.不想看前奏的请直接跳至解决方法. 问题原型: 父控件是自定义的 LinearLa ...
- swift 新特性
switch支持任意类型的数据以及各种比较操作——不仅仅是整数以及测试相等. 运行switch中匹配到的子句之后,程序会退出switch语句,并不会继续向下运行,所以不需要在每个子句结尾写break. ...