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. 编写高性能SQL

    前言:系统优化中一个很重要的方面就是SQL语句的优化.对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可达到上百倍,可见对于一个系统不是简单的能实现其功能就可以了,而是要写出高质量的SQL语 ...

  2. iOS 阶段学习第24天笔记(Block的介绍)

    iOS学习(OC语言)知识点整理 一.Block 的介绍 1)概念: block 是一种数据类型,类似于C语言中没有名字的函数,可以接收参数,也可以返回值与C函数一样被调用 封装一段代码 可以在任何地 ...

  3. MVC之前的那点事儿系列

    MVC之前的那点事儿系列,是笔者在2012年初阅读MVC3源码的时候整理的,主要讲述的是从HTTP请求道进入MVCHandler之前的内容,包括了原创,翻译,转载,整理等各类型文章,当然也参考了博客园 ...

  4. Debian7安装GCC4.8

    参考一  参考二   参考三   参考四 Ubuntu13.04下编译GCC-4.8.2源码并安装成功 CentOS 6编译安装GCC4.8      CentOS 6.4系统编译安装gcc-4.8. ...

  5. SSH实例(1)

    首先,配置struts.xml文件: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE st ...

  6. mysql存储过程中的异常处理

    http://www.cnblogs.com/cookiehu/p/4994278.html 定义异常捕获类型及处理方法: DECLARE handler_action HANDLER FOR con ...

  7. [javaSE] 反射-方法的反射

    1.如何获取某个方法 方法的名称和方法的参数列表才能唯一决定一个方法 2.方法反射的操作 method.invoke(); package com.tsh.reflect; import java.l ...

  8. Verilog学习笔记设计和验证篇(五)...............层次化事件队列

    详细的了解层次化事件队列有助于理解Verilog的阻塞赋值和非阻塞赋值功能.所谓层次化事件队列指的是用于调度仿真时间的不同Verilog事件队列.在IEEE的5.3节中定义了层次化事件队列在逻辑上分为 ...

  9. [小北De编程手记] : Lesson 06 玩转 xUnit.Net 之 定义自己的FactAttribute

    xUnit.Net本身提供了标记测试方法的标签Fact和Theory.在前面的文章<Lesson 02 玩转 xUnit.Net 之 基本UnitTest & 数据驱动>中,也对它 ...

  10. (3)JSTL的fn方法库

    fn:functions,fn之所以称之为方法库,是因为fn使用不像core,fmt标签那样遵循<prefix:tagName>的格式,而是遵循fn:methodName()的格式 < ...