zoukankan      html  css  js  c++  java
  • JavaScript Patterns 7.1 Singleton

    7.1 Singleton

    The idea of the singleton pattern is to have only one instance of a specific class. This means that the second time you use the same class to create a new object, you should get the same object that was created the first time.

    var obj = {
    
        myprop: 'my value'
    
    };
    
    var obj2 = {
    
        myprop: 'my value'
    
    };
    
    obj === obj2; // false
    
    obj == obj2; // false

    In JavaScript every time you create an object using the object literal, you’re actually creating a singleton, and there’s no special syntax involved.

    7.1.1 Using New

    when you use new  to create several objects using the same constructor, you should get only new pointers to the exact same object.

    • You can use a global variable to store the instance. This is not recommended because of the general principle that globals are bad. Plus, anyone can overwrite this global variable, even by accident.

    • You can cache in a static property of the constructor. Functions in JavaScript are objects,  so  they  can  have  properties.  You  can  have  something  like Universe.instance and cache the object there. This is a nice, clean solution with the only drawback that the instance property is publicly accessible, and code outside of yours might change it, so you lose the instance.

    • You can wrap the instance in a closure. This keeps the instance private and not available for modifications outside of your constructor at the expense of an extra closure.

    7.1.2 Instance in a Static Property

    function Universe() {
    
        // do we have an existing instance?
    
        if (typeof Universe.instance  = = = "object") {
    
            return Universe.instance;
    
        }
    
        // proceed as normal
    
        this.start_time = 0;
    
        this.bang = "Big";
    
        // cache
    
        Universe.instance = this;
    
        // implicit return:
    
        // return this;
    
    } 
    
    // testing
    
    var uni = new Universe();
    
    var uni2 = new Universe(); 
    
    uni === uni2; // true

     

    Drawback

    Instance is public

    7.1.3 Instance in a Closure

    // 7.1 Strington - Instance in closure
    
    function Universe() {
    
        // the cached instance
    
        var instance = this;
    
        // proceed as normal
    
        this.start_time = 0;
    
        this.bang = "Big";
    
        // rewrite the constructor
    
        Universe = function () {
    
            return instance;
    
        };
    
    }

     

    Drawback

    The rewritten function (in this case the constructor  Universe()) will lose any properties added to it between the moment of initial definition and the redefinition.

    // adding to the prototype
    
    Universe.prototype.nothing = true;
    
    var uni = new Universe();
    
    // again adding to the prototype after the initial object is created
    
    Universe.prototype.everything = true;
    
    var uni2 = new Universe();
    
    // only the original prototype was linked to the objects
    
    uni.nothing; // true
    
    uni2.nothing; // true
    
    uni.everything; // undefined
    
    uni2.everything; // undefined
    
    // that sounds right:
    
    uni.constructor.name; // "Universe"
    
    // but that's odd:
    
    uni.constructor === Universe; // false

    The reason that uni.constructor is no longer the same as the  Universe() constructor is because  uni.constructor still points to the original constructor, not the redefined one.

    // 7.1 Singleton - Advanced Instance in closure
    
    function Universe() {
    
        // the cached instance
    
        var instance;
    
        // rewrite the constructor
    
        Universe = function Universe() {
    
            return instance;
    
        };
    
        // carry over the prototype properties
    
        Universe.prototype = this; // this is point to the origin function
    
        // the instance
    
        instance = new Universe();    // This is initialized by the origin Universe() constructor.
    
        instance.constructor = Universe;  // Rewrite the constructor of the instance object.
    
        // all the functionality
    
        instance.start_time = 0;
    
        instance.bang = "Big";
    
        return instance;
    
    }
    
     
    
    // update prototype and create instance
    
    Universe.prototype.nothing = true; // true
    
    var uni = new Universe();
    
    Universe.prototype.everything = true; // true
    
    var uni2 = new Universe();
    
    // it's the same single instance
    
    uni === uni2; // true
    
    // all prototype properties work
    
    // no matter when they were defined
    
    uni.nothing && uni.everything && uni2.nothing && uni2.everything; // true
    
    // the normal properties work
    
    uni.bang; // "Big"
    
    // the constructor points correctly
    
    uni.constructor === Universe; // true
    Alternative solution
    var Universe;
    
    (function () {
    
        var instance;
    
        Universe = function Universe() {
    
            if (instance) {
    
                return instance;
    
            }
    
            instance = this;
    
            // all the functionality
    
            this.start_time = 0;
    
            this.bang = "Big";
    
        };
    
    }());
     

    References: 

    JavaScript Patterns - by Stoyan Stefanov (O`Reilly)

  • 相关阅读:
    多表头GridView
    Updater Application Block自动更新实施方案[源代码]
    IE和Firefox的Javascript兼容性总结
    JavaScript IE加速
    GridView汇总
    Oracle 中取当前日期的上个月最后天和第一天
    Atitit,通过pid获取进程文件路径 java php  c#.net版本大总结
    Atitit. 数据库catalog与schema的设计区别以及在实际中使用 获取数据库所有库表 java jdbc php  c#.Net
    Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle
    Atitit.一些公司的开源项目 重大知名开源项目attilax总结
  • 原文地址:https://www.cnblogs.com/haokaibo/p/javascript-Singleton.html
Copyright © 2011-2022 走看看