JavaScript之单例实战

一、概述

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

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

好了,单例模式的核心思想以及创建流程大致搞清楚了,那么我们就开始看看,在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实战-菜单特效

    以下是我自己用原生JS写的各种菜单特效,虽然网上一搜一大堆,但我还是喜欢自己来写一写! 这是上一篇:JavaScript实战(带收放动画效果的导航菜单) 下面是经过优化后的完整代码,优化了CSS样式. ...

  2. JavaScript实战(带收放动画效果的导航菜单)

    虽然有很多插件可用,但为了共同提高,我做了一系列JavaScript实战系列的实例,分享给大家,前辈们若有好的建议,请务必指出,免得误人子弟啊! ( 原创文章,转摘请注明:苏福:http://www. ...

  3. javascript 实战总结

    JavaScript的简单的知识前面已经总结  欢迎交流学习,学习靠的是理论+实践,  通过姜昊老师的JavaScript专题训练,加深了对理论知识的理解,学习新的语言越来越发现熟悉的背景,基础内容是 ...

  4. Javascript实战开发:教你使用raphael.js绘制中国地图

    最近的数据统计项目中要用到中国地图,也就是在地图上动态的显示某个时间段某个省份地区的统计数据,我们不需要flash,仅仅依靠raphael.js以及SVG图像就可以完成地图的交互操作.在本文中,我给大 ...

  5. JavaScript实战总结

    javascript中数组的22种方法:http://www.cnblogs.com/xiaohuochai/p/5682621.html 1.js闭包 2.eval函数 eval(“字符串”)  将 ...

  6. JavaScript实战实例剖析——(激励倒计时日历)

    如今JavaScript在前端开发中的地位越来越高,掌握JavaScript的深度往往能决定你职业道路深远,这次通过制作 带着倒计时功能的激励日历的小实例,进一步细致的掌握JavaScript的语法与 ...

  7. JavaScript实战(原生range和自定义特效)

    今天我又码了两个特效:一个是用原生input[type=range]的,另一个完全自定义的:下面是完整代码和演示: #tip{ position: absolute; top: 30px; left: ...

  8. 《JavaScript 实战》:JavaScript 图片滑动切换效果

    看到alibaba的一个图片切换效果,感觉不错,想拿来用用.但代码一大堆的,看着昏,还是自己来吧.由于有了做图片滑动展示效果的经验,做这个就容易得多了. 效果预览 仿淘宝/alibaba图片切换: 默 ...

  9. 《JavaScript 实战》:Tween 算法及缓动效果

    Flash 做动画时会用到 Tween 类,利用它可以做很多动画效果,例如缓动.弹簧等等.我这里要教大家的是怎么利用 Flash 的 Tween 类的算法,来做js的Tween算法,并利用它做一些简单 ...

随机推荐

  1. 安卓面试精华(Activity部分)

    过几天小弟要去面试了,当然免不了要好好复习下功课,其实很多东西也不是特别清楚,今天都当作一个回顾和巩固,希望我的这篇文章能对即将去找工作的同学有所帮助. 1. Q:什么是activity? 虽然这个问 ...

  2. IP数据报首部校验和算法

    当用google搜索IP数据报首部校验和算法的时候,总是看到的是代码,没有看到其过程,于是就有了此文,如有错误请指正.文章省略一点,呵呵   IP/ICMP/IGMP/TCP/UDP等协议的校验和算法 ...

  3. android Context的理解

    很多初入Android开发的网友向我们问到Context有什么作用,很多地方都用到它,这里Android123给这些新入门的网友做个简单的解释:  Context字面意思上下文,位于framework ...

  4. SOLR搭建企业搜索平台

    一. SOLR搭建企业搜索平台  运行环境:  运行容器:Tomcat6.0.20  Solr版本:apache-solr-1.4.0  分词器:mmseg4j-1.6.2  词库:sogou-dic ...

  5. 基于visual Studio2013解决面试题之1306奇偶位数交换

     题目

  6. MyEclipse弹出提示窗体

    MyEclipse弹出提示窗体 1.弹窗例如以下

  7. Tesseract Ocr引擎

    Tesseract Ocr引擎 1.Tesseract介绍 tesseract 是一个google支持的开源ocr项目,其项目地址:https://github.com/tesseract-ocr/t ...

  8. Qt4_VS10 程序打包发布

    源地址:http://www.2cto.com/kf/201306/217205.html 目录结构如下: ---------------------------------------------- ...

  9. PHP学习之-1.3 echo语句

    echo语句 echo语句是PHP输出语句,可以把字符串输出(字符串用双引号扩起来). 如下代码 <?php echo "Hello World!"; ?> 注意ech ...

  10. HDU 4070 Phage War

    贪心,t 大的放到前面...因为感染所有cell需要的phage的总数是一定的,所以产生phage需要的时间是一定的,只需要考虑用来感染的时间,这样考虑的话,把 t 小的放后面的话,可以发现总时间的最 ...