一单例模式
1,原生js单例模式:
1)概念
// 1,独立的对象,建2个一个xiaowang,一个xiaoli
// 2,xiaoli跟xiaowang通过门铃进行通信
// 3,先看一下xiaowang家有没有门铃 如果有门直接通过门铃通信didi,如果没有先建门
// 4,两单例之间开始通信
var xiaowang = (function (argument) {
var door;
var xiaowangHome = function (message) {
this.doorbell = message;
}
var info = {
sendMessage: function (message) {
if (!door) {
door = new xiaowangHome(message)
}
return door
}
}
return info
})()
var xiaoli = {
callXiaowang: function (meg) {
var _xw = xiaowang.sendMessage(meg);
alert(_xw.doorbell);
_xw=null;//等待垃圾回收
}
}
2)一般应用
xiaoli.callXiaowang('dididi')
// // 页面6个按钮
// document.getElementById('#a').onclick=function(){
// //很多逻辑
// var a=9;//改变量没法被其他变量获取
// }
// document.getElementById('#b').onclick=function(){
// //很多逻辑
// }
// document.getElementById('#c').onclick=function(){
// //很多逻辑
// }
// document.getElementById('#d').onclick=function(){
// //很多逻辑
// }
// document.getElementById('#e').onclick=function(){
// //很多逻辑
// }
// document.getElementById('#f').onclick=function(){
// //很多逻辑
// }
// 利用单例模式将逻辑划分到两个实例中,甚至更多
var top={
init :function(){
this.render();
this.bind()
},
a:4,
render:function(){
var me = this;
me.btna=document.querySelector("#a");
},
bind:function(){
var me=this;
me.btn.onClick=function(){
me.test();
}
},
test:function(){
a=5
}
}
var bannner={
init :function(){
this.render();
this.bind()
},
a:4,
render:function(){
var me = this;
me.btna=document.querySelector("#a");
},
bind:function(){
var me=this;
me.btn.onClick=function(){
me.test();
}
},
test:function(){
a=5;
top.a=6;
}
}
top.init()
bannner.init()
2,vue单例模式:
class SingleObject {
login() {
console.log('login...')
}
}
SingleObject.getInstance = (function () {
let instance
return function () {
if (!instance) {
instance = new SingleObject();
}
return instance
}
})()
测试
let obj1 = SingleObject.getInstance()
obj1.login()
let obj2 = SingleObject.getInstance()
obj2.login()
console.log(obj1 === obj2) // true
let obj3 = new SingleObject()
obj3.login()
console.log('obj1 === obj3', obj1 === obj3) // false
结论
就好比在一个对象的属性上,定义一个方法。
二,命令模式
<script>
// 命令模式作用:
// 1,将函数的封装,请求,调用结合为一体。
// 2,调用具体的函数解耦命令对象与接收对象
// 3,提高程序模块化的灵活性
// 注意事项:
// 1,不需要借口一致,直接调用函数忌口,以免造成浪费。
var company ={
artillery:function(num){
alert(num+'炮'+'开始战斗')
},
infantry:function(num){
alert(num+'人'+'开始战斗')
},
commander:function(order){
this[order.type](order.num)
}
}
//指挥
company.commander({type:'infantry',num:50})
company.commander({type:'artillery',num:100})
</script>
三,观察者模式,发布订阅模式区别。
1)观察者模式
<!-- <script>
// 1,多个观察者直接订阅发布者的消息。在目标发出内容改变的事件后,直接接收事件并作出响应。
// 2,观察者必须先订阅消息,否则就会接受不到消息
var pubsub=(()=>{//观察者和订阅者都写在一个对象里面
var topics={};
function subscribe(topic,fn){
if(!topics[topic]){
topics[topic]=[] ;
}
topics[topic].push(fn);
}
function publish(topic,...args){
if(!topics[topic]){
return
}
for(let fn of topics[topic]){
fn(...args)
}
}
return {subscribe,publish}
})()
pubsub.subscribe('test',function(a,b){ //订阅者A订阅了test事件
console.log(a,b);
clearTimeout(timer)
});
var timer = setTimeout(()=>{
pubsub.publish('test','123','HH');//123 HH(发布者B发布了test事件)
},2000)
</script> -->
<script>
class Watcher{//观察者订阅事件
constructor(topic,fn){
this.topics={};
if(!this.topics[topic]){
this.topics[topic]=[] ;
}
this.topics[topic].push(fn);
}
publish(topic,...args){
if(!this.topics[topic]){//避免遍历事件使用
return
}
for(let fn of this.topics[topic]){
fn(...args)
}
}
test(){
console.log(1111)
}
}
var oberser = new Watcher('test',function(a,b){ //订阅者A订阅了test事件
console.log(a,b);
});
oberser.publish('test','123','HH');
</script>
2)发布订阅模式
订阅者A和发布者B没有直接关系的,二者是通过dep订阅器进行交流的。
<script>
// 1,订阅者A和发布者B没有直接关系的,二者是通过dep订阅器进行交流的
class Dep{//订阅器收集依赖关系
constructor(){
this.subs=[]
}
addSub(sub){//添加观察者
this.subs.push(sub)
}
notify(){//通知观察者
this.subs.forEach(sub=>sub.updated())
}
}
class Watcher{
updated(){
console.log('收到订阅器发来的消息')
}
}
let dep = new Dep();
let ob = new Watcher();
//目标添加观察者了
dep.addSub(ob);
//目标发布消息调用观察者的更新方法了
dep.notify(); //update
</script>
欢迎参与分享
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。