JavaScript实现单例模式实例分享

所属分类: 网络编程 / JavaScript 阅读数: 1710
收藏 0 赞 0 分享

传统单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

实现单例核心思想

无非是用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象,接下来我们用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实现单例模式的相关学习的心得,感谢大家对脚本之家的支持。

更多精彩内容其他人还在看

jQuery 行级解析读取XML文件(附源码)

项目中应用jQuery解析读取XML语言配置文件来实现语言的调度。这是jQuery解析读取XML文件功能的测试源码,现拿出来分享。
收藏 0 赞 0 分享

JS 文件本身编码转换 图文教程

JS编码转换,这句话本身就是一句具有二重义的话。通常理解为JS文件里能转换编码的代码,但是,我所碰到的问题并不是这样的,是要解决JS文件本身的编码问题,它是UTF-8编码的还是ANSI编码的?
收藏 0 赞 0 分享

jQuery Ajax之$.get()方法和$.post()方法

load()方法通常用来从Web服务器上获取静态的数据文件,然而这并不能体现Ajax的全部价值。在项目中,如果需要传递一些参数给服务器中的页面,那么可以使用$.get()或者$.post()方法(或者是后面要讲解到的$.ajax方法)。
收藏 0 赞 0 分享

jQuery Ajax之load()方法

jQuery对Ajax操作进行了封装,在jQuery中$.ajax()方法属于最底层的方法,第2层是laod()、$.get()和$.post()方法,第3层是$.getScript()和$.getJSON()方法。
收藏 0 赞 0 分享

JavaScript 核心参考教程 内置对象

JavaScript 是根据 "ECMAScript"标准制定的网页脚本语言。这个标准由 ECMA 组织发展和维护。ECMA-262 是正式的 JavaScript 标准。
收藏 0 赞 0 分享

JavaScript 核心参考教程 RegExp对象

JavaScript 核心参考教程RegExp对象,学习正则表达式的朋友可以参考下。
收藏 0 赞 0 分享

javascript hashtable实现代码

javascript中没有像c#,java那样的哈希表(hashtable), 然而,javascript中的Array也只有一些类似于'哈希表'的非常简单功能。
收藏 0 赞 0 分享

百度留言本js 大家可以参考下

百度留言本js 大家可以参考下。
收藏 0 赞 0 分享

javascript 判断某年某月有多少天的实现代码 推荐

以前写网页的时候,经常碰到选择日期的问题,其实就是判断某年某月有多少天。
收藏 0 赞 0 分享

让iframe子窗体取父窗体地址栏参数(querystring)

突然用到,记录一下,对地址栏字符串用正则处理最好,有时间研究一下。 主要是思路。
收藏 0 赞 0 分享
查看更多