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)

JavaScript Patterns 7.1 Singleton的更多相关文章

  1. JavaScript Patterns 6.7 Borrowing Methods

    Scenario You want to use just the methods you like, without inheriting all the other methods that yo ...

  2. JavaScript Patterns 6.6 Mix-ins

    Loop through arguments and copy every property of every object passed to the function. And the resul ...

  3. JavaScript Patterns 6.5 Inheritance by Copying Properties

    Shallow copy pattern function extend(parent, child) { var i; child = child || {}; for (i in parent) ...

  4. JavaScript Patterns 6.4 Prototypal Inheritance

    No classes involved; Objects inherit from other objects. Use an empty temporary constructor function ...

  5. JavaScript Patterns 6.3 Klass

    Commonalities • There’s a convention on how to name a method, which is to be considered the construc ...

  6. JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance

    // the parent constructor function Parent(name) { this.name = name || 'Adam'; } // adding functional ...

  7. JavaScript Patterns 6.1 Classical Versus Modern Inheritance Patterns

    In Java you could do something like: Person adam = new Person(); In JavaScript you would do: var ada ...

  8. JavaScript Patterns 5.9 method() Method

    Advantage Avoid re-created instance method to this inside of the constructor. method() implementatio ...

  9. JavaScript Patterns 5.8 Chaining Pattern

    Chaining Pattern - Call methods on an object one after the other without assigning the return values ...

随机推荐

  1. 割点和桥---Tarjan算法

    使用Tarjan算法求解图的割点和桥. 1.割点 主要的算法结构就是DFS,一个点是割点,当且仅当以下两种情况:         (1)该节点是根节点,且有两棵以上的子树;         (2)该节 ...

  2. hibernate简单注释(一.1)

    **************************************************************************************************** ...

  3. mysql中变量赋值

    http://www.cnblogs.com/qixuejia/archive/2010/12/21/1913203.html sql server中变量要先申明后赋值: 局部变量用一个@标识,全局变 ...

  4. mysql-databaseython 3.4.0 with MySQL database

    Phttp://shttp://stackoverflow.com/questions/23376103/python-3-4-0-with-mysql-databasetackoverflow.co ...

  5. 解决 com.sun.*包导入错误

    解决 com.sun.*包导入错误 com.sun.image.codec.jpeg.*导入错误如何解决: com.sun.*是受限制访问的API,Eclipse 默认把受访问限制的API设成了ERR ...

  6. java servlet Json.org.jar

    servlet我们可以把他当成一个数据媒介,他最终执行的是将方法体内获取处理后的数据,返回给请求的客户端,或以XML格式,或以JSON格式 ,我这里是使用的JSON格式数据,所以下面我要说org.js ...

  7. objective-c NSMutableAttributedString

    NSMutableAttributedString 是一个很强悍的富文本处理字符串,可以方便的实现一个字符串中某个字符的样式处理.我把我下面代码实现的功能步骤说一下:首先拼接两个字符串,然后给前前半部 ...

  8. Scalaz(33)- Free :算式-Monadic Programming

    在任何模式的编程过程中都无法避免副作用的产生.我们可以用F[A]这种类型模拟FP的运算指令:A是可能产生副作用的运算,F[_]是个代数数据类型ADT(Algebraic Data Type),可以实现 ...

  9. 泛函编程(33)-泛函IO:Free Functor - Coyoneda

    在前几期讨论中我们终于推导出了Free Monad.这是一个Monad工厂,它可以把任何F[A]变成Monad.可惜的是它对F[A]是有所要求的:F必须是个Functor.Free Monad由此被称 ...

  10. Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...