javascript 设计模式之单例模式

单例模式的定义:保证一个类仅有一个实例,并提供一个全局访问他的访问点。

那么问题来了,我们如何保证一个类仅有一个实例呢,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。

在JavaScript里,实现单例的方式有很多种,其中最简单的一个方式是使用对象字面量的方法,其字面量里可以包含大量的属性和方法:

varmySingleton = {

property1: "something",

property2: "something else",

method1:function() {

console.log('hello world');

}

};

如果以后要扩展该对象,你可以添加自己的私有成员和方法,然后使用闭包在其内部封装这些变量和函数声明。只暴露你想暴露的public成员和方法,样例代码如下:

varmySingleton =function() {

/* 这里声明私有变量和方法 */

varprivateVariable = 'something private';

functionshowPrivate() {

console.log(privateVariable);

}

/* 公有变量和方法(可以访问私有变量和方法) */

return{

publicMethod:function() {

showPrivate();

},

publicVar: 'the public can see this!'

};

};

varsingle = mySingleton();

single.publicMethod();// 输出 'something private'console.log(single.publicVar);// 输出 'the public can see this!'

上面的代码很不错了,但如果我们想做到只有在使用的时候才初始化,那该如何做呢?为了节约资源的目的,我们可以另外一个构造函数里来初始化这些代码,如下:

varSingleton = (function() {

varinstantiated;

functioninit() {

/*这里定义单例代码*/

return{

publicMethod:function() {

console.log('hello world');

},

publicProperty: 'test'

};

}

return{

getInstance:function() {

if(!instantiated) {

instantiated = init();

}

returninstantiated;

}

};

})();

/*调用公有的方法来获取实例:*/

Singleton.getInstance().publicMethod();

知道了单例如何实现了,但单例用在什么样的场景比较好呢?其实单例一般是用在系统间各种模式的通信协调上,下面的代码是一个单例的最佳实践:

varSingletonTester = (function() {

//参数:传递给单例的一个参数集合functionSingleton(args) {

//设置args变量为接收的参数或者为空(如果没有提供的话)varargs = args || {};

//设置name参数this.name = 'SingletonTester';

//设置pointX的值this.pointX = args.pointX || 6;//从接收的参数里获取,或者设置为默认值//设置pointY的值this.pointY = args.pointY || 10;

}

//实例容器varinstance;

var_static = {

name: 'SingletonTester',

//获取实例的方法//返回Singleton的实例getInstance:function(args) {

if(instance === undefined) {

instance =newSingleton(args);

}

returninstance;

}

};

return_static;

})();

varsingletonTest = SingletonTester.getInstance({ pointX: 5 });

console.log(singletonTest.pointX);// 输出 5

其它实现方式

方法1:

functionUniverse() {

// 判断是否存在实例if(typeofUniverse.instance === 'object') {

returnUniverse.instance;

}

// 其它内容this.start_time = 0;

this.bang = "Big";

// 缓存Universe.instance =this;

// 隐式返回this}

// 测试varuni =newUniverse();

varuni2 =newUniverse();

console.log(uni === uni2);// true

方法2:

functionUniverse() {

// 缓存的实例varinstance =this;

// 其它内容this.start_time = 0;

this.bang = "Big";

// 重写构造函数Universe =function() {

returninstance;

};

}

// 测试varuni =newUniverse();

varuni2 =newUniverse();

uni.bang = "123";

console.log(uni === uni2);// trueconsole.log(uni2.bang);// 123

方法3:

functionUniverse() {

// 缓存实例varinstance;

// 重新构造函数Universe =functionUniverse() {

returninstance;

};

// 后期处理原型属性Universe.prototype =this;

// 实例instance =newUniverse();

// 重设构造函数指针instance.constructor = Universe;

// 其它功能instance.start_time = 0;

instance.bang = "Big";

returninstance;

}

// 测试varuni =newUniverse();

varuni2 =newUniverse();

console.log(uni === uni2);// true

// 添加原型属性Universe.prototype.nothing =true;

varuni =newUniverse();

Universe.prototype.everything =true;

varuni2 =newUniverse();

console.log(uni.nothing);// trueconsole.log(uni2.nothing);// trueconsole.log(uni.everything);// trueconsole.log(uni2.everything);// trueconsole.log(uni.constructor === Universe);// true

方式4:

varUniverse;

(function() {

varinstance;

Universe =functionUniverse() {

if(instance) {

returninstance;

}

instance =this;

// 其它内容this.start_time = 0;

this.bang = "Big";

};

} ());

//测试代码vara =newUniverse();

varb =newUniverse();

alert(a === b);// truea.bang = "123";

alert(b.bang);// 123

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容