JavaScript-单例模式

JavaScript单例模式


单例模式

  单例模式时一种较为简单的设计模式,传统的单例模式是指保证一个类只有一个实例,并提供一个访问它的全局访问点。

实现

  实现的思路是定义一个变量标志是否已经创建过实例,如果已经有实例,则返回该实例对象,否则创建一个实例并返回。用一个创建登录框的例子来说明单例模式在JavaScript中如何实现:

var loginHtml = "账号:<input type=\"text\" /><br/>密码:<input type=\"password\" />";
var createLoginDiv = function(html) {
  this.html = html;
  this.init();
};
createLoginDiv.prototype.init = function() {
  var div = document.createElement('div');
  div.innerHTML = this.html;
  document.body.appendChild(div);
};
createLoginDiv.getInstance = (function() {
  var instance = null;
  return function(html) {
    if (instance === null) {
      instance = new createLoginDiv(html);
    }
    return instance;
  };
})();
var div1 = createLoginDiv.getInstance(loginHtml);
var div2 = createLoginDiv.getInstance("账号密码");
console.log(div1 === div2); // true 并且页面只有一个登录框,为第一次创建的。

  这样实现的单例模式耦合度较低,init只负责创建登录框对象,对于返回现有对象还是创建新对象交给getInstance去做,代码也很清晰。通过这样的方式我们想要在页面上只想要一个登录框时可以得到保证,只有一个登录框,不会重复创建,节约性能。

优缺点

优点:

  • 单例模式声明一个命名空间,生成一个唯一的全局变量,用对象的方式来进行声明:var single = {…},在多人开发时可以很好的解决命名冲突的问题,方便维护、控制代码。

  • 单例只声明一个变量,如果我们在js中写多个方法,就会在window中生成多个变量,会占用更多内存单元,而且全局作用域很广,在众多处理函数中都可能改变,很难定位bug,而单例模式在创建的对象变量中可以更快的找到bug,可以大大减少bug修复时间和系统加载时间。

  • 实现同一个功能时,比通过new新创建对象对内存、资源的占用更具有优势。

缺点:

  • 扩展性和灵活性不好,当重写单例对象中的方法会破坏原有的功能,当其中某个功能要改变,其他的不变时,单例模式就不太好处理了。

  • 引用问题,当创建一个单例,var a = singleton.getInstance(“single1”),将a赋值给b,即浅拷贝,var b = a,我们知道b相当于一个引用,b和a指向的地址相同,修改b时a也会改变。在一个单例对象创建完成之后是不能随意改的。有局限性。

适用场景

  单例模式我们经常用到,在一个js中只创建一个对象,比如在一个demo.js中,我们可以这样 var demo = {},这样暴露出来的命名只有demo一个,可以大大减少对全局变量的污染。这种方法,我们在项目中会经常用到,维护起来也比较方便。

最后

  最上面的代码实现只是为了说明单例模式是一个什么样的结构,但是在我们常见的项目中,单例模式就是基本是在一个js文件中只包含一个对象,在对象里面添加属性和方法。