我是靠谱客的博主 标致野狼,最近开发中收集的这篇文章主要介绍ES6中如何使用单例模式和观察者模式,单例模式和观察者模式的详细介绍,使用ES6模块化的案例。,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

单例模式

单例模式可以保证系统中,应用该模式的类一个类只有一个实例。在JS中的单例 模式,就相当于给一个类中假如一个静态方法,然后使它返回这个类的实例化对象,他返回的这个实例化对象就是唯一的,通过这个单例模式我们就可以在其他js文件中不引用其他js获取到其中的方法,也可以用侦听来得到我们需要的数据。

举例如下,使用单例模式使用get相当于常量,ES6中是没有常量的。

get和set可以参考我之前的setter和getter文章。

html中的代码 script的代码


<script type="module">
import A from './js/A.js';
import B from './js/B.js'
import C from './js/C.js'
import Model from './js/Model.js'
new C();
Model.instance.a = new A();
Model.instance.b = new B();
Model.instance.a.play()
//Model.instance就是Model实例化的对象,通过这个对象来掉用这些方法
</script>

下面是引用的JS文件

export default class Model extends EventTarget{
_data = 0;
constructor(){
super()
}
static get instance(){
if(!Model._instance){
Object.defineProperty(Model,'_instance',{
value : new Model()
})
}
return Model._instance;
}//使用静态方法创建一个Model对象,使用Model.instance可以直接调用这个对象,并且这个对象是唯一的,可以给其中加任何东西,这个写法就被称为单例模式。
//单例模式的好处:确保只有一个实例,并且提供全局访问,不会存在变量污染问题
set data(value){
this._data = value;
Model.instance.b.play(value);
var evt = new Event('data');
this.dispatchEvent(evt)
}
get data(){
return this._data
}
}
import Model from './Model.js'
export default class A{
constructor(){
}
play(){
Model.instance.data = 100;
}
}
export default class B{
constructor(){
}
play(n){
console.log(n)
}
}
import Model from './Model.js';
export default class C{
constructor(){
console.log(Model.instance)
Model.instance.addEventListener('data',e=>this.datahandler(e))
}
datahandler(e){
console.log(Model.instance.data)
}
}

上述代码中除了单例模式还用到了中介者模式,这样我们通过这个Model.instance来连接我们的所要达到的需求,我们可以通过这种模式直接在A.js中调用B.js的内容 ,A和B是没有直接联系的。也可以通过事件抛发和监听来调取我们相应所要实现的功能,使用起来特别的方便。

观察者模式

在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。使用这种模式可以优化我们的代码,提高我们代码执行的效率

以下使用做了一个弹幕效果来举例,其中TimeManager就是观察者,而Bubble就是被观察的对象

html中的代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="con">
<video src="./video/test3.mp4" controls autoplay></video>//引入一个视频文件,因为我们需要做的是弹幕效果
</div>
<input type="text" name="msg">//输入弹幕的文本框
<script type="module">
import Main from './js/Main.js';
new Main();
</script>
</body>
</html>

JS模块的代码

Main

import Bubble from './Bubble.js';
export default class Main{
constructor(){
this.con = document.querySelector('.con');
this.input = document.querySelector('input');
this.con.style.width = this.con.firstElementChild.offsetWidth + 'px';
this.con.style.position = 'relative';
this.con.style.margin = 'auto';
this.con.style.overflow = 'hidden';
document.addEventListener('keyup',e=>this.keayHandler(e))
}
keayHandler(e){
if(e.keyCode!==13) return;
if(this.input.value.trim().length===0) return;
let b = new Bubble(this.input.value);
b.appendTo(this.con);
this.input.value = ''
}
}
//Bubble
import Utils from './Utils.js';
import TimeManager from './TimeManager.js';
export default class Bubble{
x;
speed = 3;
constructor(msg){
this.elem = this.createElem(msg)
}
createElem(msg){
if(this.elem) return this.elem;
let div = Utils.ce('div',{
whiteSpace:'nowrap',
position:'absolute',
color : 'red'
})
div.textContent = msg;
return div
}
appendTo(parent){
if(typeof parent === 'string') parent = document.querySelector(parent);
if(!HTMLElement.isPrototypeOf(parent.constructor)) return;
parent.appendChild(this.elem);
var rect = parent.getBoundingClientRect();
Object.assign(this.elem.style,{
left: rect.width + 'px',
top : Math.random()*rect.height / 2 +'px'
})
this.x = rect.width;
TimeManager.instance.add(this)
}
update(){
this.x -=this.speed;
this.elem.style.left = this.x + 'px';
if(this.x<-this.elem.offsetWidth) TimeManager.instance.remove(this)
}
dispose(){
this.elem.remove();
this.elem = null
}
}

TimeManager

export default class TimeManager{
list = [];
ids;
constructor(){
}
static get instance(){
if(!TimeManager._instance){
Object.defineProperty(TimeManager,'_instance',{
value: new TimeManager()
})
}
return TimeManager._instance;
}
add(elem){
if(this.list.indexOf(elem) > -1) return;
this.list.push(elem);
if(this.ids || this.list.length===0) return;
this.ids = setInterval(()=> this.update(),16)
}
remove(elem){
var index = this.list.indexOf(elem);
if(index < 0) return;
this.list.splice(index,1);
elem.dispose();
if(this.list.length>0 || this.ids===undefined) return;
clearInterval(this.ids);
this.ids = undefined;
}
update(){
for(let i = 0; i < this.list.length; i++){
this.list[i].update();
}
}
}

Utils是我自己的一个小型js库其中的ce是创建元素方便使用的,下面这个是ce的方法。


static ce(type,style,parent){
var elem=document.createElement(type);
if(style){
for(var prop in style){
elem.style[prop]=style[prop];
}
}
if(typeof parent==="string") parent=document.querySelector(parent);
if(parent) parent.appendChild(elem);
return elem;
}

以上代码通过TimeManager来观察Bubble的实例化对象的移动来判断是否开启定时器,当没有弹幕是自己就会停止,不论是代码的优化还是效率的有很促进的作用。

最后

以上就是标致野狼为你收集整理的ES6中如何使用单例模式和观察者模式,单例模式和观察者模式的详细介绍,使用ES6模块化的案例。的全部内容,希望文章能够帮你解决ES6中如何使用单例模式和观察者模式,单例模式和观察者模式的详细介绍,使用ES6模块化的案例。所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部