传统单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
实现单例核心思想
无非是用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象,接下来我们用JavaScript来强行实现这个思路,请看代码:
var Singleton = function( name ){ this.name = name; }; Singleton.prototype.getName = function(){ alert ( this.name ); }; Singleton.getInstance = (function(){ var instance = null; return function( name ){ if ( !instance ){ instance = new Singleton( name ); } return instance; } })();
我们通过Singleton.getInstance来获取Singleton类的唯一对象,这样确实是没问题的,但是js本身是没有类这种概念的,所以我们强行用传统单例思想来实现是没有任何意义的,这样的代码又臭又长(其实是我自己看着不舒服嘻嘻嘻)。下面我们使用JavaScript的闭包来实现一个单例,请看代码:
var CreateDiv = (function(){ var instance; var CreateDiv = function( html ){ if ( instance ){ return instance; } this.html = html; this.init(); return instance = this; }; CreateDiv.prototype.init = function(){ var div = document.createElement( 'div' ); div.innerHTML = this.html; document.body.appendChild( div ); }; return CreateDiv; })(); var a = new CreateDiv( 'sven1' ); var b = new CreateDiv( 'sven2' ); alert ( a === b ); // true
可以看到,这样我们确实用闭包来实现了一个单例,但这个代码还是高度耦合的,CreateDiv的构造函数实际上负责了两件事情。第一是创建对象和执行初始化init方法,第二是保证只有一个对象。这样的代码是职责不明确的,现在我们要把这两个工作分开,构造函数就负责构建对象,至于判断是返回现有对象还是构造新的对象并返回,我们交给另外一个函数去完成,其实也就是为了满足一个编程思想:单一职责原则。这样的代码才能更好的解耦,请看下面代码:
var CreateDiv = function (html) { this.html = html; this.init(); }; CreateDiv.prototype.init = function () { var div = document.createElement('div'); div.innerHTML = this.html; document.body.appendChild(div); }; var ProxySingletonCreateDiv = (function () { var instance; return function (html) { if (!instance) { instance = new CreateDiv(html); } return instance; } })(); var a = new ProxySingletonCreateDiv('sven1'); var b = new ProxySingletonCreateDiv('sven2'); alert(a === b); //true
可以看到,现在我们的构造函数CreateDiv现在只负责构造对象,至于是返回现有对象还是构造新的对象并返回,这件事我们交给了代理类proxySingletonCreateDiv来处理,这样的代码看着才舒(zhuang)服(bi)嘛!
最后贴一个高度抽象的单例模式代码,惰性单例的精髓!
//单例模式抽象,分离创建对象的函数和判断对象是否已经创建 var getSingle = function (fn) { var result; return function () { return result || ( result = fn.apply(this, arguments) ); } };
形参fn是我们的构造函数,我们只要传入任何自己需要的构造函数,就能生成一个新的惰性单例。比如说传入创建一个女朋友的构造函数,并且调用getSingle(),就能生成一个新的女朋友。如果以后再调getSingle(),也只会返回刚才创建的那个女朋友。至于新女朋友——不存在的。
单例常用场景
只需要生成一个唯一对象的时候,比如说页面登录框,只可能有一个登录框,那么你就可以用单例的思想去实现他,当然你不用单例的思想实现也行,那带来的结果可能就是你每次要显示登陆框的时候都要重新生成一个登陆框并显示(耗费性能),或者是不小心显示出了两个登录框。
以上就是我们给大家分享的关于JS实现单例模式的相关学习的心得,感谢大家对小牛知识库的支持。
本文向大家介绍Python单例模式实例分析,包括了Python单例模式实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python单例模式的使用方法。分享给大家供大家参考。具体如下: 方法一 1.禁用__init__方法,不能直接创建对象。 2.__instance,单例对象私有化。 3.@staticmethod,静态方法,通过类名直接调用。 4.__lock,代码锁。 5.继承
本文向大家介绍JavaScript设计模式之单例模式实例,包括了JavaScript设计模式之单例模式实例的使用技巧和注意事项,需要的朋友参考一下 《Practical Common Lisp》的作者 Peter Seibel 曾说,如果你需要一种模式,那一定是哪里出了问题。他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案。 不管是弱类型或强类型,静态或动态语言,命令式或说
本文向大家介绍php单例模式实现方法分析,包括了php单例模式实现方法分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php单例模式实现方法。分享给大家供大家参考。具体如下: 希望本文所述对大家的php程序设计有所帮助。
本文向大家介绍c# 单例模式的实现,包括了c# 单例模式的实现的使用技巧和注意事项,需要的朋友参考一下 记一下学习单例模式的笔记: 单例就是要保证该类仅有一个实例。实现完全封闭的单例(外部不能new)其实就要两点要求: 全局访问:需要一个该类型的全局静态变量,每次获取实例时都要判断它是否null,不存在new,存在通过一个方法直接返回该值获取实例来保证对象唯一; 实例化控制:new实例不能
原始问题:程序读取旧配置文件(.ini)的输入 小节:漂移 田块:亩 价值:5
本文向大家介绍Javascript单例模式的介绍和实例,包括了Javascript单例模式的介绍和实例的使用技巧和注意事项,需要的朋友参考一下 前言 其实和其他编程语言一样,Javascript同样拥有着很多种设计模式,比如单例模式、代理模式、观察者模式等,熟练运用Javascript的设计模式可以使我们的代码逻辑更加清晰,并且更加易于维护和重构。 本文将会介绍Javascript中的单例模式,在