美文网首页
JS单体模式

JS单体模式

作者: 贪恋冬天的幸福 | 来源:发表于2019-11-20 22:24 被阅读0次

    JavaScript中并没有类,因此对单体咬文嚼字的定义严格说来并没有意义。但是JavaSctipt中具有new语法可使用构造函数来创建对象,而且有时可能需要使用这种语法的单体实现。这种思想在于当使用同一个构造函数以new操作符来创建多个对象时,应该仅获得指向完全相同的对象的新指针。
    下面的代码片段显示了其预期行为:

    var one = new Universe();
    var two = new Universe();
    one === two; // 结果为true
    

    在JavaScript中要实现上述模式,需要Universe构造函数缓存该对象实例this,以便当第二次调用该构造函数时能够创建并返回同一个对象。有多种选择可以实现这一目标:

    • 可以使用全局变量来存储该实例。
    • 可以在构造函数的静态属性中缓存该实例。
    • 可以将该实例包装在闭包中。
      但是全局变量容易被覆盖,因此不推荐此种方法。在静态属性中缓存该实例的缺点在于此实例属性可被公开访问,在外部代码中可能会修改此属性。而在闭包中的实例,可以保证实例的私有性,并且保证该实例不会被构造函数之外的代码所修改。其代价就是带来了额外的闭包开销。
      下面,让我们来看看第二种和第三种方法的实现实例。

    静态属性中的实例

    function Universe() {
       if (typeof Universe.instance === 'object') {
           return Universe.instance;
       }
       this.start_time = 0;
       this.bang = "Big";
       Universe.instance = this;
       // 隐式返回
       // return this;
    }
    

    测试用例如下:

    var one = new Universe();
    var two = new Universe();
    one === two; // 结果为true
    

    闭包中的实例

    function Universe() {
       // 缓存实例
       var instance;
       Universe = function Universe() {
         return instance;
       }
       // 保留原型属性
       Universe.prototype = this;
       // 实例
       instance = new Universe();
       // 重置构造函数指针
       instance.constructor = Universe;
       // 所有功能
       instance.start_time = 0;
       instance.bang = "Big";
    
       return instance;
    }
    

    测试用例如下:

    Universe.prototype.something = "some thing";
    var one = new Universe();
    
    Universe.prototype.some1thing = "some 1 thing";
    var two = new Universe();
    
    console.log(one === two); // true
    console.log(one.something, two.something); // some thing some thing
    console.log(one.some1thing, two.some1thing);// some 1 thing some 1 thing
    console.log(one.bang, two.bang); // Big Big
    console.log(one.constructor === Universe); // true
    
    

    另外一种解决方案是将构造函数和实例包装在即时函数中,代码如下:

    var Universe;
    (function () { 
        var instance;
        Universe = function Universe() {
            if (instance) {
               return instance;
            }
            instance = this;
            //所有功能
            instance.start_time = 0;
            instance.bang = "Big";
        }
    }());
    
    

    相关文章

      网友评论

          本文标题:JS单体模式

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