一、概述

所谓单例模式,顾名思义即一个类只有一个实例。

所以,当我们创建一个实例时,就必须判断其是否已经存在了这个实例,如果已经存在了这个实例,那么就返回这个已经存在的实例,无需再创建一个单例模式嘛,核心就是一个类只有一个 实例;如果不存在,就创建这个实例咯。

好了,单例模式的核心思想以及创建流程大致搞清楚了,那么我们就开始看看,在Javascript的世界中,具体该怎么实现呢?

二、实战一

核心思路:利用Javascript的作用域,形成闭包,从而可以创建私有变量(假设我们将这个私有变量取名为instance),然后将创建的实例赋予这个私有变量instance就ok了。每当想创建这个类的实例时,先判断instance是否已经引用了存在的实例,如果没有引用,即这个类没有被创建实例,so创建一个实例,然后将其赋予给instance;如果instance已经引用,即已存在了该类的实例,so无需再创建,直接使用这个instance就ok了。

第一步:执行匿名函数,防止命名空间污染。在匿名函数中,首先定义个上述提到的私有变量instance以及一个类。这个类,我假设它有名字(name)和年龄(age)两个属性字段以及一个输出他们名字的方(displayInfo)哈。

'use strict'
var singletonAccepter =(function(){
//默认将instance赋予null
var instance = null;
//类:SupposeClass
function SupposeClass( args ){
var args = args || {};
this.name = args.name || 'Monkey';
this.age = args.age || 24;
};
SupposeClass.prototype = {
constructor: SupposeClass,
displayInfo: function(){
console.log('name: ' + this.name + ' age: ' + this.age);
}
};
})();

第二步:利用return + 对象字面量,将我们想,向外暴露的东东,往外抛。

如下:

return {
//类的名字
name: 'SupposeClass',
//创建类的实例方法
getInstance: function( args ){
//利用私有变量instance实现单例模式
if( instance === null ){
instance = new SupposeClass( args );
}
return instance;
}
};

最后,合并第一步第二步的代码就形成了一个单例模式啦。

如下:

'use strict'
var singletonAccepter =(function(){
//默认将instance赋予null
var instance = null;
//类:SupposeClass
function SupposeClass( args ){
var args = args || {};
this.name = args.name || 'Monkey';
this.age = args.age || 24;
};
SupposeClass.prototype = {
constructor: SupposeClass,
displayInfo: function(){
console.log('name: ' + this.name + ' age: ' + this.age);
}
};
return {
//类的名字
name: 'SupposeClass',
//创建类的实例方法
getInstance: function( args ){
//利用私有变量instance实现单例模式
if( instance === null ){
instance = new SupposeClass( args );
}
return instance;
}
};
})();

接下来,我们检验一下写的这个单例模式。在上述代码中,在类SupposeClass中加入console.log,如果只创建了它的一个实例,那么就只会打印一个日志哦。
修改代码如下:

'use strict'
var singletonAccepter =(function(){
var instance = null;
function SupposeClass( args ){
var args = args || {};
this.name = args.name || 'Monkey';
this.age = args.age || 24;
//检验单例模式
console.log('this is created!');
};
SupposeClass.prototype = {
constructor: SupposeClass,
displayInfo: function(){
console.log('name: ' + this.name + ' age: ' + this.age);
}
};
return {
name: 'SupposeClass',
getInstance: function( args ){
if( instance === null ){
instance = new SupposeClass( args );
}
return instance;
}
};
})();

调用两次getInstance方法,看看打印几条记录

singletonAccepter.getInstance();
singletonAccepter.getInstance();

执行代码,打开chrome截图如下:

鉴定完毕,只被实例一次。

三、实战二

思路:利用属性来判断是否已存在实例。
什么意思?
在Javascript的世界里,类(function)不也是对象嘛,so对其赋予一个属性instance,用来引用创建的实例,通过判断instance是否已引用创建的实例就OK咯。

如下:

function singletonAccepter( args ){
//判断Universe.instance是否已存在实例
if(typeof singletonAccepter.instance === 'object'){
return singletonAccepter.instance;
}
this.name = args.name || 'Monkey';
this.age = args.age || 24;
singletonAccepter.instance = this;
};
singletonAccepter.prototype = {
constructor: singletonAccepter,
displayInfo: function(){
console.log('name: ' + this.name + ' age: ' + this.age);
}
};
四、实战三

在Javascript的世界里,this是引用的对象。
还记得JavaScript是怎么通过new创建对象的么?
new:
  1、创建一个新的对象,这个对象的类型时object;
  2、将这个对象的__proto__隐指针指向原型prototype;
  3、执行构造函数,当this被提及的时候,代表新创建的对象;
  4、返回新创建的对象。
  注:倘若在最后return了,那么return的是基本类型,例如3,则无效;否则是引用类型,则返回这个引用类型。

注意第3点了么?

当new后,this代表新创建的对象。so,我们可以利用闭包,在类中声明一个变量instance来引用创建的实例。然后再重写类,就OK啦。

如下:

function singletonAccepter( args ){
var instance = null;
var args = args || {};
this.name = args.name || 'Monkey';
this.age = args.age || 24;
//将instance引用创建的实例this
instance = this;
//重写构造函数
singletonAccepter = function(){
return instance;
}
};
singletonAccepter.prototype = {
constructor: singletonAccepter,
displayInfo: function(){
console.log('name: ' + this.name + ' age: ' + this.age);
}
};

JavaScript之单例实战的更多相关文章

  1. Javascript 设计模式 单例

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/30490955 一直很喜欢Js,,,今天写一个Js的单例模式实现以及用法. 1.单 ...

  2. javascript的单例/单体模式(Singleton)

    首先,单例模式是对象的创建模式之一,此外还包括工厂模式.单例模式的三个特点:1,该类只有一个实例2,该类自行创建该实例(在该类内部创建自身的实例对象)3,向整个系统公开这个实例接口 Java中大概是这 ...

  3. Javascript设计模式学习二(单例)

    定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点 普通的单例模式: 使用一个变量来标记当前是否已经为某个类创建过对象,如果是的话,在下一次获取该类的实例时,直接返回之前创建的对象.比如:使用 ...

  4. 010-Scala单例对象、伴生对象实战详解

    010-Scala单例对象.伴生对象实战详解 Scala单例对象详解 函数的最后一行是返回值 子项目 Scala伴生对象代码实战 object对象的私有成员可以直接被class伴生类访问,但是不可以被 ...

  5. Scala 深入浅出实战经典 第79讲:单例深入讲解及单例背后的链式表达式

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  6. javascript学习(9)——[设计模式]单例

    单例模式,相信大家对此都不陌生,我们主要讲下javascript中几个比较常见的设计模式: (1).普通的单体 (2).具有局部变量的强大单体 (3).惰性单体 (4).分支单体 下面我们就一一进行介 ...

  7. JavaScript 设计模式之----单体(单例)模式

    设计模式之--单体(单例)模式 1.介绍 从本章开始,我们会逐步介绍在JavaScript里使用的各种设计模式实现,在这里我不会过多地介绍模式本身的理论,而只会关注实现.OK,正式开始. 在传统开发工 ...

  8. JavaScript设计模式之单例模式【惰性单例】

    在提高开发水平,往中高级前端工程师中,利用设计模式是必不可少的一条道路.掌握设计模式的思想远远比硬套重要,因为设计模式是一种思想,不局限于开发语言.但实际上由于语言的特性不同,往往在实现的时候会有不少 ...

  9. Scala单例对象、伴生对象实战详解

    1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...

随机推荐

  1. Vagrant 基础全面解析

    这篇 Vagrant 入门文章将带你创建一个 Vagrant 项目,这个过程将会用到 Vagrant 所提供的主要基本特性.如果想了解 Vagrant 能为你带来哪些好处,可以阅读 Vagrant 官 ...

  2. 异步任务队列Celery在Django中的使用

    前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...

  3. 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车

     阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...

  4. 操作系统篇-调用门与特权级(CPL、DPL和RPL)

    || 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在前两篇文章(<操作系统篇-浅谈实模式与保护模式>和<操作系统篇-分段机制与GDT|LDT>)中,我们提到 ...

  5. 【原】AFNetworking源码阅读(二)

    [原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...

  6. ASP.NET Core应用针对静态文件请求的处理[2]: 条件请求与区间请求

    通过调用ApplicationBuilder的扩展方法UseStaticFiles注册的StaticFileMiddleware中间件帮助我们处理针对文件的请求.对于StaticFileMiddlew ...

  7. Hawk 6. 高级话题:子流程系统

    子流程的定义 当流程设计的越来越复杂,越来越长时,就难以进行管理了.因此,采用模块化的设计才会更加合理.本节我们介绍子流程的原理和使用. 所谓子流程,就是能先构造出一个流程,然后被其他流程调用.被调用 ...

  8. System.Guid ToString五中格式

    参考:https://msdn.microsoft.com/en-us/library/97af8hh4.aspx 测试代码: using System; using System.Collectio ...

  9. AutoMapper的介绍与使用(一)

    软件环境 vs2015 asp.net mvc 5 .NET Framework 4.5.2 AutoMapper 5.2.0.0 AutoMapper安装 新建asp.net mvc 项目 Auto ...

  10. 【开源】专业K线绘制[K线主副图、趋势图、成交量、滚动、放大缩小、MACD、KDJ等)

    这是一个iOS项目雅黑深邃的K线的绘制. 实现功能包括K线主副图.趋势图.成交量.滚动.放大缩小.MACD.KDJ,长按显示辅助线等功能 预览图 最后的最后,这是项目的开源地址:https://git ...