JavaScript设想形式与开辟实践系列之单例形式

本系列为《JavaScript设想形式与开辟实践》(作者:曾探)进修总结,如想深切相识,请支撑作者原版

单例形式

完成单例形式

单例形式的定义是:保证一个类唯一一个实例,并供应一个接见它的全局接见点
单例形式是一种常常运用的形式,有一些对象我们每每只须要一个,比方登录窗口,这个窗口是唯一的,不管我们点击多少次登录按钮,这个窗口只会被建立一次,那末这个窗口就适合用单例形式来建立。

要完成一个规范的单例形式并不庞杂,无非是用一个变量来标志当前是不是已为某个类建立过对象,假如是,则在下一次猎取该类的实例时,直接返回之前建立的对象。代码以下:

var Singleton=function(name){
    this.name=name;
    this.instance=null;
};
Singleton.prototype.getName=function(){
    alert(this.name);
};
Singleton.getInstance=function(){
    if(!this.instance){
        this.instance=new Singleton(name);
    }
    return this.instance;
};
var a=Singleton.getInstance('sven1');
var b=Singleton.getInstance('sven2');

alert(a===b);//true

或许

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类的唯一对象,这类体式格局相对简朴,然则不通明。跟以往经由过程new XXX的体式格局猎取对象差别,这里偏要运用Singleton.getInstance来猎取对象,所以这段代码的意义并不大。

通明的单例形式

我们如今的目的是完成一个通明的单例类。

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

虽然如今完成了一个通明的单例类的编写,但它一样有一些瑕玷。为了把instance封装起来,我们运用了自实行的匿名函数和闭包,而且让这个匿名函数返回真正的Singleton组织要领,这增加了一些顺序的庞杂度,浏览起来也不是很惬意。
假定我们某天须要让这个单例类变成一个一般的类,即能够发生多个实例,那我们必需改写CreateDiv组织函数,这类修正会带来许多不必要的贫苦。

用代办完成单例形式

我们起首建立一个一般的CreateDiv类:

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);
};

接下来引入代办类ProxySingletonCreate:

var ProxySingletonCreate = (function() {
  var instance;
  return function(html) {
    if (!instance) {
      instance = new CreateDiv(html);
    }
    return instance;
  }
})();

var a = new ProxySingletonCreate('sven1');
var b = new ProxySingletonCreate('sven2');
console.log(a === b);

这样一来,CreateDivProxySingletonCreate组合起来,完成了单例形式的结果。

JavaScript中的单例形式

前面提到的几种单例形式的完成,更多的是靠近传统面向对象言语中的完成,单例对象从中建立而来。但JavaScript现实上是一门无类的言语,所以生搬单例形式的观点并没有意义。
单例形式的中心是:确保只要一个实例,并供应全局接见
全局变量不是单例形式,但在现实运用中,我们常常会把全局变量当成单例来运用。
比方:

var a = {};

全局变量能够满足上述的两个前提,但却存在许多问题:它很轻易形成定名空间污染。作为一般的开辟者,我们有必要削减全局变量的运用,一下几种体式格局能够相对下降全局变量带来的定名污染。

运用定名空间

最简朴的要领依然是运用对象字面量体式格局:

var namespace1={
    a:function(){
    },
    b:function(){
    }
};

我们还能够动态的建立定名空间:

var myApp = {};
myApp.namespace = function(name) {
  var parts = name.split('.');
  var current = myApp;
  for (var i in parts) {
    if (!current[parts[i]]) {
      current[parts[i]] = {};
    }
    current = current[parts[i]];
  }
};

myApp.namespace('event');
myApp.namespace('dom.style');

console.log(myApp);

运用闭包封装私有变量

var user=(function(){
    var _name='sven',_age=29;
    return {
        getUserInfo:function(){
            return _name+'_'+_age;
        }
    }
})();

惰性单例

惰性单例指的是在须要的时刻才建立对象实例惰性单例是单例形式的重点,这类手艺在现实开辟中异常有效
我们先抽掏出一个治理单例的逻辑对象:

var getSingle=function(fn){
    var result;
    return function(){
        return result||(result=fn.apply(this.arguments));
    }
};

建立对象的要领fn被当作参数传入getSingle。

var getSingle = function(fn) {
  var result;
  return function() {
    return result || (result = fn.apply(this.arguments));
  };
};

var createLoginLayer = function() {
  var div = document.createElement('div');
  div.innerHTML = '我是登录窗';
  div.style.width = '100px';
  div.style.height = '100px';
  div.style.background = 'red';
  document.body.appendChild(div);
  return div;
};

aa = getSingle(createLoginLayer);
aa();

result变量由于身在闭包中,永久不会被烧毁。在未来的要求中,假如result已被赋值,那末他将返回这个值。
以下是演示地点:

惰性单例演示地点
其他演示地点

    原文作者:司想君
    原文地址: https://segmentfault.com/a/1190000004565894
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞