单体模式的思想在于保证一个特定类仅有一个实例。这意味着当第二次使用同一个类创建的新对象的时候,应该得到与第一个所创建的对象完全相同。

javacript中并没有类,因此对单体咬文嚼字的定义严格来说并没有意义。但是javascript具有new语法可使用构造函数来创建对象,而且有时需要使用这种语法的单体实现。这种思想在于当使用同一个构造函数以new操作符来创建多个对象时,应该仅获得指向完全相同的对象的新指针。

下面的代码显示了其预期行为:

var nui = new Universe();
var nui2 = new Universe();
nui === nui2; //结果为true

上面例子中,uni对象仅在第一次调用构造函数时被创建。在第二次创建时会返回同一个对象。这就是为什么nui === nui2,我们可以写出2种做法。

静态属性中的实例

下面代码是一个在Universe构造函数静态属性中缓存单个实例的列子:

function Universe(){

    //如果有实例,返回出去
if(typeof Universe.instance === 'object'){
return Universe.instance;
}
this.start_time = 0;
this.bang = 'Big'; //缓存
Universe.instance = this;
}
//测试
var nui = new Universe();
var nui2 = new Universe();
console.log( nui === nui2); //结果为true

正如你所看到的,这种做法的缺点在于instance是公开的。虽然其他代码不太可能会无意中修改该属性,但是仍有这种可能。

闭包中的实例

另外一种实现类似于类的单体方法是采用闭包来保护单个实例。

代码如下:

function Universe(){

    //缓存实例
var instance = this; this.start_time = 0;
this.bang = 'Big'; Universe = function(){
return instance;
}
}
//测试:
var uni = new Universe();
var uni2 = new Universe();
console.log( uni == uni2 ); //结果为tur

这种做法会丢失所有在初始定义和重定义时刻时间添加到它里面的属性。这里的特定情况下,任何添加到Universe的原型中的对象都不会存在指向由原始实现所创建实例的活动连接。

通过下面一些测试,可以看到这个问题:

向原型添加属性

Universe.prototype.nothing = true;
var uni = new Universe();
Universe.prototype.everything = true;
var uni2 = new Universe();

开始测试:
仅有最初的原型
连接到对象上
console.log(uni.nothing); //结果为true
console.log(uni2.nothing); //结果为true console.log(uni.everything); //结果为undefined
console.log(uni2.everything); //结果为undefined 结果看上去是正确的
console.log( uni.constructor.name ); //结果为Universe
console.log( uni.constructor === Universe); //结果为false

之所以uni.constructor不再与Universe()构造函数相同,是因为nui.constructor仍然指向了原始的构造函数,而不是重新定义的那个构造函数。

从需求上来说,如果需要使用原型和构造函数指针按照预期的那样运行,那么可以通过做一些调试来实现这个目标:

function Universe(){

    //缓存实例
var instance; //重写构造函数
Universe = function Universe(){
return instance;
} //保留原型属性
Universe.prototype = this; //实例
instance = new Universe(); //重置构造函数指针
instance.constructor = Universe; //所有功能
instance.start_time = 0;
instance.bang = 'Big'; return instance;
} //更新原型并创建实例
Universe.prototype.nothing = true; //结果为true
var uni = new Universe();
Universe.prototype.everything = true; //结果为true
var uni2 = new Universe(); //相同的实例
console.log( uni === uni2 ); //结果为true //所有原型属性
console.log( uni.nothing && uni.everything && uni2.nothing && uni2.everything ); //结果为true //构造函数指针正确
console.log( uni.constructor === Universe); //结果为true

一个对象字面量创建一个简单的对象也是一个单体的例子:

var obj = {
myprop : 'my value'
};
var obj2 = {
myprop : 'my value'
}; console.log( obj === obj2 ); //false
console.log( obj == obj2 ); //false

  

  

javascript单体模式的更多相关文章

  1. javascript --- 设计模式之单体模式(一)

    单体是一个用来划分命名空间并将一些相关的属性与方法组织在一起的对象,如果她可以被实例化的话,那她只能被实例化一次(她只能嫁一次,不能二婚). 单体模式是javascript里面最基本但也是最有用的模式 ...

  2. javascript中单体模式的实现

    单体模式作为一种软件开发模式在众多面向对象语言中得到了广泛的使用,在javascript中,单体模式也是使用非常广泛的,但是由于javascript语言拥有其独特的面向对象方式,导致其和一些传统面向对 ...

  3. 读书笔记之 - javascript 设计模式 - 单体模式

    单体是一个用来划分命名空间,并将一批相关方法和属性组织在一起的对象,如果它可以被实例化,那么它只能被实例化一次. 单体模式,就是将代码组织为一个逻辑单元,这个逻辑单元中的代码可以通过单一的变量进行访问 ...

  4. javascript设计模式(单体模式)

    主要内容: js中最基本.应用最广的模式就是单体模式,实现原理是将代码组织为一个逻辑单元,这个逻辑单元中的代码可以通过单一的变更进行访问,确保对象只存在一份实例. 单体模式的特点: 在网页中使用全局变 ...

  5. javascript设计模式之单体模式

    一入前端深似海,刚入前端,以为前端只是div+css布局外加jquery操作DOM树辣么简单.伴随着对前端学习的深入,发现前端也是博大精深,而且懂得越多,才发现自己越无知,所以一定不能停下脚步的学习. ...

  6. JavaScript设计模式——单体模式

    一:单体模式简介: 是什么:将代码组织为一个逻辑单元,这个单元中的代码通过单一的变量进行访问.只要单体对象存在一份实例,就可以确信自己的所有代码使用的是同样的全局资源. 用途:1.用来划分命名空间,减 ...

  7. Javascript设计模式(2)-单体模式

    单体模式 1. js最简单的单体模式 对象字面量:把一批有一定关联的方法和属性组织在一起 // 对象字面量 var Singleton = { attr1: true, attr2: 10, meth ...

  8. JavaScript中的单体模式四种实现方式

    /* 1 简单单体 */ var Singleton = { attr1: 1 , method1:function(){ //do sth } }; alert(Singleton.attr1); ...

  9. javascript设计模式-单体模式

    场景:假设有一个Girl(美女)实体,该实体拥有姓名.年龄两个属性,拥有显示姓名和洗澡两个方法,下面分步骤构造该实体. 1.用简单基本单体模式: var Girl1 = { name:"昭君 ...

随机推荐

  1. 20145208实验一 Java开发环境的熟悉

    20145208实验一 Java开发环境的熟悉 使用JDK编译.运行简单的java程序 命令行下程序开发 在命令行下建立实验目录,然后创建并进入该目录后的子目录. 编译并运行一个代码 使用IDEA 编 ...

  2. 第四章 Js的面向对象的初窥视(天生的哈希表)

    对象就有键值对 var speaker = { text: "Hello World", say: function(){ console.log("Hello Worl ...

  3. UITextField实现左侧空出一定的边距

    就是通过uitextfield的leftview来实现的,同时要设置leftviewmode. 如果设置左右边距,需要再加上rightView功能 -(void)setTextFieldLeftPad ...

  4. [BZOJ 1486][HNOI2009]最小圈(二分答案+dfs写的spfa判负环)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1486 分析:容易想到先二分答案x,然后把所有边的权值-x,那么如果图中存在权值和为0的 ...

  5. 《TCP/IP详解卷1:协议》第6章 ICMP:Internet控制报文协议-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  6. WEB前端开发规范

    WEB前端开发规范 规范目的 为提高团队协作效率, 便于后台人员添加功能及前端后期优化维护, 输出高质量的文档, 特制订此文档.本文档如有不对或者不合适的地方请及时提出, 经讨论决定后方可更改. 基本 ...

  7. NumberFormat类的用法

    NumberFormat.getInstance()方法返回NumberFormat的一个实例(实际上是NumberFormat具体的一个子类,例如DecimalFormat), 这适合根据本地设置格 ...

  8. iOS边练边学--级联菜单的两种实现方法

    一.方法1:如图,图中的两个tableView分别交给两个控制器来管理 重点难点:categoryTableView被点击之后,subcategoryTableView要取得相应的数据进行刷新,所以s ...

  9. Hibernate-一对多的关系维护

    一对多 和多对一 一般是看需求来确定的,很多时候都是设置成双向的 举个最最普通的离子 :一个班级里面有多个学生 多个学生属于一个班级 从学生表来看 就是多对一的关系 从班级表来看就是一对多的关系 需求 ...

  10. Tomcat server.xml详解

    Server.xml的结构大致 <Server port="8005" shutdown="SHUTDOWN"> <Service name= ...