前端开发那些事儿

设计模式 - 单例模式

2021-03-20  本文已影响0人  vivianXIa

本来想一片文章写出所有的设计模式,但是我发现,以我的整理理解,篇幅估计不会太短,就每一种设计模式都单独写吧。平时不记录的话,合上电脑,一个星期后,相当于没看过。

es5实现方式

var Singleton = function(name) {
    this.name = name;
    //一个标记,用来判断是否已将创建了该类的实例
    this.instance = null;
}
// 提供了一个静态方法,用户可以直接在类上调用
Singleton.getInstance = function(name) {
    // 没有实例化的时候创建一个该类的实例
    if(!this.instance) {
        this.instance = new Singleton(name);
    }
    // 已经实例化了,返回第一次实例化对象的引用
    return this.instance;
}

es6 实现方式

class Singleton {
    constructor(name) {
        this.name = name;
        this.instance = null;
    }
    // 构造一个广为人知的接口,供用户对该类进行实例化
    static getInstance(name) {
        if(!this.instance) {
            this.instance = new Singleton(name);
        }
        return this.instance;
    }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>加油,奥里给</title>
</head>
<style>
    /**
 * index.scss
 * - Add any styles you want here!
 */
    
    body {
        background: #f5f5f5;
    }
    
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    
    .top-bar {
        display: flex;
        justify-content: space-between;
        height: 40px;
        line-height: 40px;
        background-color: black;
    }
    
    .top-bar_left {
        padding-left: 20px;
        font-size: 22px;
        color: #fff;
    }
    
    .top-bar_right {
        display: flex;
        color: #fff;
        padding-right: 40px;
    }
    
    .top-bar_right div {
        cursor: pointer;
    }
    
    .top-bar_right div:hover {
        color: #ccc;
    }
    
    .login-btn {
        margin-right: 20px;
    }
    
    .mask-layer {
        display: flex;
        justify-content: center;
        position: absolute;
        width: 100%;
        height: 100%;
        padding-top: 8%;
        background-color: rgba(0, 0, 0, 0.3);
    }
    
    .login-wrapper {
        width: 400px;
        height: 200px;
        padding-left: 20px;
        background-color: #fff;
        border: 1px solid #ccc;
    }
    
    .login-title {
        display: flex;
        justify-content: space-between;
        padding: 10px 10px 0 0;
    }
    
    .close-btn {
        cursor: pointer;
    }
    
    .user-input {
        margin-top: 20px;
    }
    
    .login-text {
        display: inline-block;
        width: 60px;
    }
    
    .btn-wrapper {
        display: flex;
        margin-top: 20px;
    }
    
    .btn-wrapper button {
        padding: 0 8px;
        cursor: pointer;
    }
    
    .clear-btn {
        margin-left: 10px;
    }
</style>

<body>
    <nav class="top-bar">
        <div class="top-bar_left">
            LTH BLOG
        </div>
        <div class="top-bar_right">
            <div class="login-btn">登陆</div>
            <div class="signin-btn">注册</div>
        </div>
    </nav>
    <script>
        class Login {

            //构造器
            constructor() {
                this.init();
            }

            //初始化方法
            init() {
                //新建div
                let mask = document.createElement('div');
                //添加样式
                mask.classList.add('mask-layer');
                //添加模板字符串
                mask.innerHTML =
                    `
  <div class="login-wrapper">
    <div class="login-title">
      <div class="title-text">登录框</div>
      <div class="close-btn">×</div>
    </div>
    <div class="username-input user-input">
      <span class="login-text">用户名:</span>
      <input type="text">
    </div>
    <div class="pwd-input user-input">
      <span class="login-text">密码:</span>
      <input type="password">
    </div>
    <div class="btn-wrapper">
      <button class="confrim-btn">确定</button>
      <button class="clear-btn">清空</button>
    </div>
  </div>
  `;
                //插入元素
                document.body.insertBefore(mask, document.body.childNodes[0]);
                //注册关闭登录框事件
                Login.addCloseLoginEvent();
            }

            //静态方法: 获取元素
            static getLoginDom(cls) {
                return document.querySelector(cls);
            }

            //静态方法: 注册关闭登录框事件
            static addCloseLoginEvent() {
                this.getLoginDom('.close-btn').addEventListener('click', () => {
                    //给遮罩层添加style, 用于隐藏遮罩层
                    this.getLoginDom('.mask-layer').style = "display: none";
                })
            }

            //静态方法: 获取实例(单例)
            static getInstance() {
                if (!this.instance) {
                    this.instance = new Login();
                } else {
                    //移除遮罩层style, 用于显示遮罩层
                    this.getLoginDom('.mask-layer').removeAttribute('style');
                }
                return this.instance;
            }
        }
        // /注册点击事件
        Login.getLoginDom('.login-btn').addEventListener('click', () => {
            console.log('zhe')
            Login.getInstance();
        })
    </script>
</body>

</html>

购物车

class  Cart{
   constructor(){
        this.list=[]
    }
    add(data){
        this.list.push(data)
    }
    del(id){
        this.list=this.list.filter(item=>{
            if(item.id==id){
              return false
            }
            return true
        })
    }
    render(){
          var dom=$('cartDom')
          var html=''
          for(let i=0;i<this.list.length;i++){
            html+='<div>'+this.list[i].tit+'</div>'
          }
          dom.append(html)
    }
    static getInstance(){
        if(!this.instance){
          this.instance=new Cart();
        }else{
          console.log('已经创建过cart对象')
          return
        }
        return  this.instance
     }
}

let cart=Cart.getInstance()
cart.add({id:1,tit:商品name.......})
cart.del(1)

闭包版

function  StorageBase(){
    StorageBase.prototype.getItem=function(){
        return  localStorage.getItem(key)
     }
    StorageBase.prototype.setItem=function(){
        return  localStorage.setItem(key,value)
    }
}
const  Storage1=(function(){
  let instance=null
  return  function (){
      if(!instance){
         instance=new StorageBase()
       }  
        return instance
   }
})()
const storage3=new Storage1()
console.log(storage3)
const storage2=new Storage1()
storage3.setItem('name','张三')
storage3.getItem('name') //张三
storage2.getItem('name')//张三

单例模式得应用大家最熟悉得有vuex vue-router

实例:全局数据存储对象 (vuex)

function store(){
  if(store.instance){
      return store.instance
  }
store.instance=this
}
//同
function store(){
  if(!(this instanceof store)){
      return new store()
  }
}

上面得代码 可以new 也可以直接使用 ,这里使用了一个静态变量instance来记录是否有进行过实例化,如果实例化了就返回这个实例,如果没有实例化说明使第一次调用,就会把this赋给这个静态变量,因为是使用new 调用,这时候得this指向得就是实例化出来得对象,并且最后会隐式得返回this

var  a=new store()
var b=store()
a==b

说的看到比较好的文章:
https://www.jianshu.com/p/7fa6ea107eff

上一篇下一篇

猜你喜欢

热点阅读