这篇文章主要介绍了什么是单例单例模式、使用场景,提供了3个示例给大家参考

什么是单例?

单例要求一个类有且只有一个实例,提供一个全局的访问点。因此它要绕过常规的控制器,使其只能有一个实例,供使用者使用,而使用着不关心有几个实例,因此这是设计者的责任

In JavaScript, Singletons serve as a shared resource namespace which isolate implementation code from the global namespace so as to provide a single point of access for functions.

在javascript中,单例被当做一个全局的命名空间,提供一个访问该对象的一个点。

使用场景

In practice, the Singleton pattern is useful when exactly one object is needed to coordinate others across a system. 

单例比较适用于一个对象和其他系统进行交互。

类比

单例有点类似于一个小组的小组长,在一段时间内只有一个小组长,有小组长来指定组员的工作,分配和协调和组员的工作。

实例1:这个是最简单的单例,通过key,value的形式存储属性和方法

var A = {
xx:,
yy:,
B:function(el){ },
C:function(el){ },
D:function(el){ },
E:function(el){ }
}

实例2:首先创建一个实例的引用,然后判断这个实例是否存在,如果不存在那么就创建,存在的话,就直接返回,保证有且只有一个。

var mySingleton = (function () {

// Instance 存储一个单例实例的引用
var instance; function init() { // Singleton // 私有的方法和变量
function privateMethod(){
console.log( "I am private" );
} var privateVariable = "Im also private"; return { // 共有的方法和变量
publicMethod: function () {
console.log( "The public can see me!" );
}, publicProperty: "I am also public"
}; }; return { // 如果实例不存在,那么创建一个
getInstance: function () { if ( !instance ) {
instance = init();
} return instance;
} }; })(); var singleA = mySingleton;
var singleB = mySingleton;
console.log( singleA === singleB ); // true

实例3:

var SingletonTester = (function () {
// options: an object containing configuration options for the singleton
// e.g var options = { name: "test", pointX: 5};
function Singleton( options ) {
// set options to the options supplied
// or an empty object if none are provided
options = options || {};
// set some properties for our singleton
this.name = "SingletonTester";
this.pointX = options.pointX || ;
this.pointY = options.pointY || ;
}
// our instance holder
var instance;
// an emulation of static variables and methods
var _static = {
name: "SingletonTester",
// Method for getting an instance. It returns
// a singleton instance of a singleton object
getInstance: function( options ) {
if( instance === undefined ) {
instance = new Singleton( options );
}
return instance;
}
};
return _static;
})();
var singletonTest = SingletonTester.getInstance({
pointX:
});
// Log the output of pointX just to verify it is correct
// Outputs: 5
console.log( singletonTest.pointX );

单例模式

 
    单例模式也称作为单子模式,更多的也叫做单体模式。为软件设计中较为简单但是最为常用的一种设计模式。
 
    下面是维基百科对单例模式的介绍:
    在应用单例模式时,生成单例的类必须保证只有一个实例的存在,很多时候整个系统只需要拥有一个全局对象,才有利于协调系统整体的行为。比如在整个系统的配置文件中,配置数据有一个单例对象进行统一读取和修改,其他对象需要配置数据的时候也统一通过该单例对象来获取配置数据,这样就可以简化复杂环境下的配置管理。

    单例模式的思路是:一个类能返回一个对象的引用(并且永远是同一个)和一个获得该实例的方法(静态方法,通常使用 getInstance 名称)。那么当我们调用这个方法时,如果类持有的引用不为空就返回该引用,否者就创建该类的实例,并且将实例引用赋值给该类保持的那个引用再返回。同时将该类的构造函数定义为私有方法,避免其他函数使用该构造函数来实例化对象,只通过该类的静态方法来得到该类的唯一实例。
 
    对于 JS 来说,巨大的灵活性使得其可以有多种方式实现单例模式,使用闭包方式来模拟私有数据,按照其思路可得:

  1. var single = (function(){
  2. var unique;
  3. function getInstance(){
  4. if( unique === undefined ){
  5. unique = new Construct();
  6. }
  7. return unique;
  8. }
  9. function Construct(){
  10. // ... 生成单例的构造函数的代码
  11. }
  12. return {
  13. getInstance : getInstance
  14. }
  15. })();
    以上,unique便是返回对象的引用,而 getInstance便是静态方法获得实例。Construct 便是创建实例的构造函数。
    可以通过 single.getInstance() 来获取到单例,并且每次调用均获取到同一个单例。这就是 单例模式 所实现的效果。
 
    不过,对于JS来说,显然以上循规蹈矩的方式显得过于笨重,在不同的场景以不同的方式实现单体模式正是 JS 的优势
    

实现1: 最简单的对象字面量

  1. var singleton = {
  2. attr : 1,
  3. method : function(){ return this.attr; }
  4. }
  5. var t1 = singleton ;
  6. var t2 = singleton ;
    那么很显然的, t1 === t2 。
 
    十分简单,并且非常使用,不足之处在于没有什么封装性,所有的属性方法都是暴露的。对于一些需要使用私有变量的情况就显得心有余而力不足了。当然在对于 this 的问题上也是有一定弊端的。
 
 

实现2:构造函数内部判断

    其实和最初的JS实现有点类似,不过是将对是否已经存在该类的实例的判断放入构造函数内部。

  1. function Construct(){
  2. // 确保只有单例
  3. if( Construct.unique !== undefined ){
  4. return Construct.unique;
  5. }
  6. // 其他代码
  7. this.name = "NYF";
  8. this.age="24";
  9. Construct.unique = this;
  10. }
  11. var t1 = new Construct() ;
  12. var t2 = new Construct() ;
    那么也有的, t1 === t2 。
    也是非常简单,无非就是提出一个属性来做判断,但是该方式也没有安全性,一旦我在外部修改了Construct的unique属性,那么单例模式也就被破坏了。
    

实现3 : 闭包方式

    对于大着 灵活 牌子的JS来说,任何问题都能找到 n 种答案,只不过让我自己去掂量孰优孰劣而已,下面就简单的举几个使用闭包实现单例模式的方法,无非也就是将创建了的单例缓存而已。
 

  1. var single = (function(){
  2. var unique;
  3. function Construct(){
  4. // ... 生成单例的构造函数的代码
  5. }
  6. unique = new Constuct();
  7. return unique;
  8. })();
    只要 每次讲 var t1 = single; var t2 = single;即可。 与对象字面量方式类似。不过相对而言更安全一点,当然也不是绝对安全。
    如果希望会用调用 single() 方式来使用,那么也只需要将内部的 return 改为
    
    return function(){
        return unique;
    } 
    以上方式也可以使用 new 的方式来进行(形式主义的赶脚)。当然这边只是给了闭包的一种例子而已,也可以在 Construct 中判断单例是否存在 等等。 各种方式在各个不同情况做好选着即可。
 

总结

    总的来说,单例模式相对而言是各大模式中较为简单的,但是单例模式也是较为常用并且很有用的模式。在JS中尤为突出(每个对象字面量都可以看做是一个单例么~)。
    记住,是否严格的只需要一个实例对象的类(虽然JS没有类的概念),那么就要考虑使用单例模式。
    使用数据缓存来存储该单例,用作判断单例是否已经生成,是单例模式主要的实现思路。

js单例模式详解实例的更多相关文章

  1. js对象详解(JavaScript对象深度剖析,深度理解js对象)

    js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...

  2. 9种Java单例模式详解(推荐)

    单例模式的特点 一个类只允许产生一个实例化对象. 单例类构造方法私有化,不允许外部创建对象. 单例类向外提供静态方法,调用方法返回内部创建的实例化对象.  懒汉式(线程不安全) 其主要表现在单例类在外 ...

  3. Message,MessageQueue,Looper,Handler详解+实例

    Message,MessageQueue,Looper,Handler详解+实例 原文地址 Android的Handler使用(这篇简单介绍Handler的使用) 一.几个关键概念 1.Message ...

  4. iOS开发——UI篇OC篇&UICollectionView详解+实例

    UICollectionView详解+实例 实现步骤: 一.新建两个类 1.继承自UIScrollView的子类,比如HMWaterflowView * 瀑布流显示控件,用来显示所有的瀑布流数据 2. ...

  5. Android:weight,margin,padding详解实例

    weight详解 weight是用来等比例划分区域的属性. 案例代码 <LinearLayout xmlns:android="http://schemas.android.com/a ...

  6. 常用经典SQL语句大全完整版--详解+实例 (存)

    常用经典SQL语句大全完整版--详解+实例 转 傻豆儿的博客 http://blog.sina.com.cn/shadou2012  http://blog.sina.com.cn/s/blog_84 ...

  7. iOS之UI--使用SWRevealViewController 实现侧边菜单功能详解实例

     iOS之UI--使用SWRevealViewController 实现侧边菜单功能详解实例 使用SWRevealViewController实现侧边菜单功能详解 下面通过两种方法详解SWReveal ...

  8. gvoory脚本中关于HttpClient使用详解实例

    一.gvoory脚本中关于HttpClient使用详解实例 HttpClient:是一个接口 首先需要先创建一个DefaultHttpClient的实例 HttpClient httpClient=n ...

  9. 常用经典SQL语句大全完整版--详解+实例 《来自网络,很全没整理,寄存与此》

    常用经典SQL语句大全完整版--详解+实例 下列语句部分是Mssql语句,不可以在access中使用. SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML ...

随机推荐

  1. WEB前端 [编码] 规则浅析

    前言 说到前端安全问题,首先想到的无疑是XSS(Cross Site Scripting,即跨站脚本),其主要发生在目标网站中目标用户的浏览器层面上,当用户浏览器渲染整个HTML文档的过程中出现了不被 ...

  2. Codeforces 807C - Success Rate(二分枚举)

    题目链接:http://codeforces.com/problemset/problem/807/C 题目大意:给你T组数据,每组有x,y,p,q四个数,x/y是你当前提交正确率,让你求出最少需要再 ...

  3. CCF CSP 201403-2 窗口

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201403-2 窗口 问题描述 在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标 ...

  4. 【LOJ】#2067. 「SDOI2016」硬币游戏

    题解 c一样的就是一个独立的游戏 我们对于2和3的指数 sg[i][j] 表示\(c \cdot 2^i \cdot 3^j\)的棋子,只有这个硬币是反面,翻转的硬币是正面的sg值 枚举sg函数所有可 ...

  5. 【LOJ】#2538. 「PKUWC2018」Slay the Spire

    题解 由于强化卡都是大于1的,我们分析一下就会发现,尽可能多的用强化卡,至少用一张攻击卡,一定是每组卡牌的最优选择 所以我们把攻击卡和强化卡从大到小排序 我们设\(g[i][j]\)表示前i张卡牌里选 ...

  6. idea集成项目管理工具 --- Maven 并且【配置tomcat】

    介绍: 1.项目管理工具 POM    Porject Object Model 2.可以管理项目中的的jar包依赖 3.maven   jar包中央仓库:http://mvnrepository.c ...

  7. date time insert

    DATE=`date '+%m/%d/%Y'`TIME=`date '+%H:%M:%S'` sed -i '1i1***** start*****' test.kshsed -i '2i\ REPO ...

  8. [ 原创 ] Java基础8--什么叫做重载

    重载是在同一个类中,有多个方法名相同,参数列表不同(参数个数不同,参数类型不同),与方法的返回值无关,与权限修饰符无关,B中的参数列表和题目的方法完全一样了.

  9. python opencv3 图像与原始字节转换

    git: https://github.com/linyi0604/Computer-Vision # coding:utf8 import cv2 import numpy import os &q ...

  10. 机器学习之路: python 支持向量机 LinearSVC 手写字体识别

    使用python3 学习sklearn中支持向量机api的使用 可以来到我的git下载源代码:https://github.com/linyi0604/MachineLearning # 导入手写字体 ...