我们知道JavaScript设计模式有很多,本文主要给大家介绍JavaScript观察者模式的内容。那么究竟JavaScript观察者模式是什么呢?如何实现?接下来我们详细的了解看看。
概述
观察者模式又被称为发布-订阅模式,是设计模式中的一种行为型模式;
定义:
观察者模式定义了一种一对多的对象依赖关系,当被依赖的对象的状态发生了改变,所有依赖它的对象都会得到通知;
白话解释:
假如你去苹果专卖店买最新款的iphone11,因为iphone11刚出来不久,正处旺季,供货不足;当你去专卖店的时候,店员告诉你暂时没货了,但是你可以留下你的联系方式,如果货到了,会第一时间通知;当然你肯定不会每天都去专卖店问iphone11到货没有,也不会天天给专卖店打电话,因为你有你自己的工作和生活,不可能有那么多闲暇时间;所以此时,店员让你留下联系方式,到货了第一时间通知你,不会给你带来麻烦,而你只需要等着专卖店的电话即可;而这种方法就是一种典型的观察者模式;
首先我们还是来分析一下:
1.订阅方法:我们把联系方式给专卖店店员是属于一种消息订阅的消息,因为只有这样你才能及时的知道iphone11到货了,所有我们需要一个订阅行为的具体方法;
2.预订列表:要知道iphone11是属于新版iphone,所以肯定不会是只有你一个人去预订,所以店员为了方便统计还需要一个预订列表来统计所有的预订者的联系方式以及预订手机版本信息,所以我们这里先给它定义为一个对象;key代表是预订者的联系方式,value代表预订手机版本信息;
3.发布方法:当iphone11到货的时候,专卖店肯定要根据预订列表来进行统一发布消息("iphone11到货了,大家快来抢!!!"),所以专卖店需要一个发布方法来实行具体的发布行为;、
4.取消订阅:万物相对,能订阅肯定就能取消订阅;在等待iphone11到货通知的时候,你急着用手机,所以直接买了华为的某款,所以iphone11暂时对你来说需求不大,因为你已经有了手机所以专卖店的iphone11是否到货对你来说没有任何意义了;所以此时你不想被打扰,需要取消订阅消息;所以我们需要一个取消订阅方法来实现具体的取消订阅的行为;
观察者模式的应用场景
1、DOM事件
如果你是一个前端开发人员,不管你读这篇文章之前是否已经了解观察者模式,但是我能肯定你已经用过观察者模式;
document.body.addEventListener('click', function() {
console.log('hello world!');
});
这段代码看着眼熟吗?是的,这是一个DOM事件的监听;我们通过给body订阅click事件(click相当于上面的订阅方法),因为浏览器并不知道你什么时候点击鼠标,所以等你触发click事件的时候才会触发函数给你发布通知(发布方法);DOM事件就是一个观察者模式的实现;
2、vue双向绑定v-model
我们作为前端开发人员,肯定知道vue是一个MVVM模式的框架;vue的核心就是双向绑定,那么双向绑定的实现实际上就是一种观察者模式;因为你首先绑定了一个数据之后(订阅方法),浏览器并不知道你什么时候修改,你页面上所有绑定了该数据或者依赖该数据的节点其实就是一个预订列表,只有等你修改了该数据的值的时候,vue才会通知(发布方法)到依赖该数据的方法/数据进行相应的操作或刷新;
观察者模式的实现
//定义商家
var merchants = {};
//定义预订列表
merchants.orderList = {};
//将增加的预定者添加到预订列表中 (订阅方法)
merchants.listen = function(id,info){
//如果存在
if(!this.orderList[id]){
// (预订列表)
this.orderList[id] = [];
}
// 将用户的预定的产品信息存入到数组中
this.orderList[id].push(info);
}
//发布信息(发布方法)
merchants.publish = function(){
var id = Array.prototype.shift.call(arguments);
var infos = this.orderList[id];
if(!infos || infos.length === 0){
console.log("您还没有预定信息");
return false;
}
for(var i = 0;i < infos.length;i++){
console.log("预定成功");
console.log("尊敬的用户:")
infos[i].apply(this,arguments);
console.log("到货了");
}
}
//取消订阅
merchants.remove = function(id,fn){
var infos = this.orderList[id];
if(!infos){ return false}
if(!fn){
console.log(123);
}else{
for(var i = 0;i < infos.length;i++){
if(infos[i] === fn){
infos.splice(i,1);
}
}
}
大型站长资讯类网站! https://www.0818zz.com