Js单例模式 (Singleton Pattern)

更新日期: 2019-06-21阅读: 1.5k标签: 模式

概念

单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。  

核心:确保只有一个实例,并提供全局访问。


实现思路

一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常命名为getIntance);当我们调用这个方法时,类持有的引用不为空则返回这个引用,如果为空须创建该类实例并将实例的引用赋予该类保持的引用;同时将该类的构造函数定义为私有方法,那么其他环境就无法通过调用该类的构造函数来实例化该类的对象,只能通过该类提供的静态方法得到该类唯一的实例。


实现 Java 语言中的单例模式

  public class Singleton {
      private static final Singleton {
          private Singleton() { };

          public static Singleton getInstance {
              if (INSTANCE == null) {
                  synchronized(Singleton.class) {
                      if(INSTANCE = null) {
                         INSTANCE = new Singleton()
                      }
                  }

              }
              return INSTANCE;
          }
      }
  }


实现 JavaScript 语言中的单例模式

let Singleton = function(name){
    this.name = name;
}
Singleton.prototype.getName = function() {
    console.log(this.name)
}
Singleton.getInstance = (function() {
   let instance;
   return function(name) {
       if(instance) return instance;
       return instance = new Singleton(name)
   }
})()
let s1 = Singleton.getInstance('owen'); // Singleton {name: "owen"}
let s2 = Singleton.getInstance('guowen'); // Singleton.getInstance('guowen');
s1 === s2 // true

JavaScript中单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。


应用

命名空间

使用命名空间可以降低全局变量带来的命名污染;
最简单的方法是对象字面量

const globalWeb = {
    a() {},
    b() {}
    // ...
}

或者使用闭包

let Singleton = (function(){
    let instance;
    let init = function() {
    let name = 'owen';
        return {
            name,
            data(){
                return {}
            },
            method:{ }
        }
    }
    return {
        getInstance() {
            if(instance) return instance;
            return instance = init()
        }
    }
}())
let app = Singleton.getInstance() // {name: "owen", data: ƒ, method: {…}}


惰性单例

惰性单例指在需要的时候才创建对象实例,在实现开发中非常有用,即目标对象只有在使用的时候才被创建,而不是页面加载好时创建。

模态框示例

点击一个按钮弹窗一个模态框,很明显页面是唯一的,一次不会弹窗多个模态框的情况

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>modal box</title>
    <style>
    * {
        margin: 0;
        padding:0;
    }
   html{
   width:100%;
   height:100%;
   }
    .Owen {
        width:30%;
        height:30%;
        margin:10% auto;
    }
    #modal {
        width:100%;
        height:100%;
        position:fixed;
        left:0;
        top:0;
        background: rgba(0, 0, 0, 0.52);
        display:none;
    }
    .main{
        width:30%;
        height:30%;
        margin:10% auto;
        text-align: center;
        background-color: #b0e8ff;
    }
    </style>
</head>
<body>
   <div class="Owen">
        <button>Owen</button>
   </div>
    <div id="modal">
        <div class="main">
          <div>
                我是弹框
          </div>
        </div>
    </div>
</body>
<script>

window.onload = function(){
    let openModal = document.querySelector("button")
    let modal = document.querySelector("#modal")
    openModal.addEventListener('click',function(){
       modal.style.display = 'block'
    })
}

</script>
</html>

第一种方法是在页面加载完成时创建好这个弹框,一开始就是隐藏的,只有点击按钮的时候才显示,这种方式有一个问题,就是我们进入页面,只是看看其他内容,不做任何操作;这样就造成资源浪费

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>modal box</title>
    <style>
    * {
        margin: 0;
        padding:0;
    }
   html{
   width:100%;
   height:100%;
   }
    .Owen {
        width:30%;
        height:30%;
        margin:10% auto;
    }
    #modal {
        width:100%;
        height:100%;
        position:fixed;
        left:0;
        top:0;
        background: rgba(0, 0, 0, 0.52);
    }
    .main{
        width:30%;
        height:30%;
        margin:10% auto;
        padding:20px;
        text-align: right;
        background-color: #b0e8ff;
        position:relative;
    }
    .main div {
        text-align: center;
    }
    .main span {
        display: inline-block;
        padding:5px;
        cursor:pointer;
    }
    </style>
</head>
<body>

    <div class="Owen">
        <button>点我</button>
    </div>

</body>
<script>
window.onload = function(){
    init()
}
function init() {
    let openModal = document.querySelector("button")
    let createModal =( function() {
        let flag;
        // 生成 Modal 容器
        let div = document.createElement('div')
        div.id = "modal"
        div.style.display = "none";
        return function() {
            if(flag) return div;
            flag = true;
            let fra = document.createDocumentFragment();
            // 添加 Modal 内容
            els = `<div>
                    <span>×</span>
                        <div>
                            我是弹框
                        </div>
                    </div>
                    `
            div.innerHTML = els;
            fra.appendChild(div)
            document.body.appendChild(fra)
            // 关闭 Modal
            let close = document.querySelector('.close')
            close.addEventListener('click',function(){
                flag = false;
                document.body.removeChild(div)
            })

            return div
        }
    }())
    // 显示 Modal
    openModal.addEventListener('click',function(){
       createModal().style.display = "block";
    })
}
</script>
</html>

第二种方法,只执行一次dom的创建修改操作,不用频繁的创建和删除节点,提高资源利用率;


链接: https://www.fly63.com/article/detial/4312

js设计模式之单例模式,javascript如何将一个对象设计成单例

单例模式是我们开发中一个非常典型的设计模式,js单例模式要保证全局只生成唯一实例,提供一个单一的访问入口,单例的对象不同于静态类,我们可以延迟单例对象的初始化,通常这种情况发生在我们需要等待加载创建单例的依赖。

前端设计模式:从js原始模式开始,去理解Js工厂模式和构造函数模式

工厂模式下的对象我们不能识别它的类型,由于typeof返回的都是object类型,不知道它是那个对象的实例。另外每次造人时都要创建一个独立的person的对象,会造成代码臃肿的情况。

JavaScript设计模式_js实现建造者模式

建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象

html和xhtml,DOCTYPE和DTD,标准模式和兼容模式

主要涉及知识点: HTML与XHTML,HTML与XHTML的区别,DOCTYPE与DTD的概念,DTD的分类以及DOCTYPE的声明方式,标准模式(Standard Mode)和兼容模式(Quircks Mode),标准模式(Standard Mode)和兼容模式(Quircks Mode)的区别

前端四种设计模式_JS常见的4种模式

JavaScript中常见的四种设计模式:工厂模式、单例模式、沙箱模式、发布者订阅模式

javascript 策略模式_理解js中的策略模式

javascript 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。 策略模式利用组合,委托等技术和思想,有效的避免很多if条件语句,策略模式提供了开放-封闭原则,使代码更容易理解和扩展, 策略模式中的代码可以复用。

javascript观察者模式_深入理解js中的观察者模式

javascript观察者模式又叫发布订阅模式,观察者模式的好处:js观察者模式支持简单的广播通信,自动通知所有已经订阅过的对象。存在一种动态关联,增加了灵活性。目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。

Vue中如何使用方法、计算属性或观察者

熟悉 Vue 的都知道 方法methods、计算属性computed、观察者watcher 在 Vue 中有着非常重要的作用,有些时候我们实现一个功能的时候可以使用它们中任何一个都是可以的

我最喜欢的 JavaScript 设计模式

我觉得聊一下我爱用的 JavaScript 设计模式应该很有意思。我是一步一步才定下来的,经过一段时间从各种来源吸收和适应直到达到一个能提供我所需的灵活性的模式。让我给你看看概览,然后再来看它是怎么形成的

Flutter 设计模式 - 简单工厂

在围绕设计模式的话题中,工厂这个词频繁出现,从 简单工厂 模式到 工厂方法 模式,再到 抽象工厂 模式。工厂名称含义是制造产品的工业场所,应用在面向对象中,顺理成章地成为了比较典型的创建型模式

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!