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. Android SurfaceView实现静态于动态画图效果

    本文是基于Android的SurfaceView的动态画图效果,实现静态和动态下的正弦波画图,可作为自己做图的简单参考,废话不多说,先上图, 静态效果: 动态效果: 比较简单,代码注释的也比较详细,易 ...

  2. MSSQL - 存储过程取出5条热点新闻

    USE [DB_News] GO /****** Object: StoredProcedure [dbo].[SelectHotNews] Script Date: 2015/7/8 13:34:4 ...

  3. http权威指南 telnet

    对于winXP 1.先启动一个telnet程序连接到TCP服务器中. telnet www.joes-hardware.com 80 2.在连接上的TCP服务器的telnet程序窗口中同时按下 &qu ...

  4. qtcreator +vs2013 开发xp下使用的程序

    在qtcreator 开发,使用vs2013的编辑器开发出来的exe不能在xp下使用, 只需要在pro文件添加 QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5. ...

  5. PHP学习之-1.5 字符串

    字符串 一个字符串是用双引号扩起来的一个词或者一个句子,比如 "Hello Word" ,你可以使用PHP语言输入这个字符串,像这样 <?php echo "Hel ...

  6. zTree实现地市县三级级联Action类

    zTree实现地市县三级级联Action类 ProvinceAction.java: /** * @Title:ProvinceAction.java * @Package:com.gwtjs.str ...

  7. HDU 4839 The Game of Coins _(:зゝ∠)_

    The Game of Coins mark: #include"cstdio" #include"iostream" #include"queue& ...

  8. linux kill进程和子进程小trick

           我们的hive web是调用polestar restful service(https://github.com/lalaguozhe/polestar-1)来执行具体的hive或者s ...

  9. 综述-如何克服HTML5的“性工能”障碍

    http://ask.dcloud.net.cn/docs HTML5自出现以来,几经风雨,虽看似很有前途,但实际使用问题太多,DCloud为此踩了无数坑.但我们从未放弃,我们加入了W3C,发起了 H ...

  10. WordPress数据备份

    服务器钱用光了要关了或者是服务器想要搬家,需要备份各种数据. 今天简单的备份了一下在服务器上面wordpress各种文件和资源. wordpress的数据主要分两个部分,一个是文字部分的:一个是附件部 ...