美文网首页
设计模式——单例模式

设计模式——单例模式

作者: spfi | 来源:发表于2018-09-07 15:14 被阅读0次

    一、单例模式
    1、单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
    2、创建单例模式:用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象
    var Singleton = function( name ){
    this.name = name;
    this.instance = null;
    };

        Singleton.prototype.getName = function(){ 
            alert ( this.name ); 
        }; 
    
      Singleton.getInstance = function( name ){ 
          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; 
           } 
    })();
    

    3、透明的单例模式
    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 
    

    4、用代理实现单例模式
    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 );
    };
    接下来引入代理类 proxySingletonCreateDiv:
    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 );
    5、JavaScript 中的单例模式
    (1. 使用命名空间
    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.dir( MyApp ); 
    

    // 上述代码等价于:

    var MyApp = {
    event: {},
    dom: {
    style: {}
    }
    };
    2)使用闭包封装私有变量
    这种方法把一些变量封装在闭包的内部,只暴露一些接口跟外界通信:
    var user = (function(){
    var __name = 'sven',
    __age = 29;

    return { 
        getUserInfo: function(){ 
            return __name + '-' + __age; 
        } 
    } 
    

    })();
    我们用下划线来约定私有变量__name 和__age,它们被封装在闭包产生的作用域中,外部是
    访问不到这两个变量的,这就避免了对全局的命令污染。
    6、惰性单例
    1)惰性单例指的是在需要的时候才创建对象实例。惰性单例是单例模式的重点,这种技术在实际开发中非常有用,有用的程度可能超出了我们的想象
    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.display = 'none';
    document.body.appendChild( div );
    return div;
    };

    var createSingleLoginLayer = getSingle( createLoginLayer );

    document.getElementById( 'loginBtn' ).onclick = function(){
    var loginLayer = createSingleLoginLayer();
    loginLayer.style.display = 'block';
    };
    下面我们再试试创建唯一的 iframe 用于动态加载第三方页面:
    var createSingleIframe = getSingle( function(){
    var iframe = document.createElement ( 'iframe' );
    document.body.appendChild( iframe );
    return iframe;
    });

    document.getElementById( 'loginBtn' ).onclick = function(){
    var loginLayer = createSingleIframe();
    loginLayer.src = 'http://baidu.com';
    };
    这种单例模式的用途远不止创建对象,比如我们通常渲染完页面中的一个列表之后,接下来
    要给这个列表绑定 click 事件,如果是通过 ajax 动态往列表里追加数据,在使用事件代理的前提
    下,click 事件实际上只需要在第一次渲染列表的时候被绑定一次,但是我们不想去判断当前是
    否是第一次渲染列表,如果借助于 jQuery,我们通常选择给节点绑定 one 事件:
    var bindEvent = function(){
    $( 'div' ).one( 'click', function(){
    alert ( 'click' );
    });
    };

    var render = function(){
    console.log( '开始渲染列表' );
    bindEvent();
    };

    render();
    render();
    render();
    如果利用 getSingle 函数,也能达到一样的效果。代码如下:
    var bindEvent = getSingle(function(){
    document.getElementById( 'div1' ).onclick = function(){
    alert ( 'click' );
    }
    return true;
    });

    var render = function(){
    console.log( '开始渲染列表' );
    bindEvent();
    };

    render();
    render();
    render();
    可以看到,render 函数和 bindEvent 函数都分别执行了 3 次,但 div 实际上只被绑定了一个
    事件

    相关文章

      网友评论

          本文标题:设计模式——单例模式

          本文链接:https://www.haomeiwen.com/subject/rfycgftx.html