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. EC笔记,第一部分:3.尽量使用const

    03.尽量使用const 1.const概述 2.返回const 为何要返回一个const? 因为如果不返回const,程序员可能写出fun(a,b)=c;这样的代码,也许是因为打字错误可能写出类似i ...

  2. mysql中变量赋值

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

  3. Spring发展历程总结

    目前很多公司的架构,从Struts2迁移到了SpringMVC.你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢? 既然这样,我们从源头说起.Stru ...

  4. javascript-String

    概述 String对象是JavaScript原生提供的三个包装对象之一,用来生成字符串的包装对象实例. var s = new String("abc"); typeof s // ...

  5. php取默认值以及类的继承

    (1)对于php的默认值的使用和C++有点类似,都是在函数的输入中填写默认值,以下是php方法中对于默认值的应用: <?phpfunction makecoffee($types = array ...

  6. ahjesus自定义隐式转换和显示转换

    implicit    关键字用于声明隐式的用户定义类型转换运算符. 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换. 参考戳此 explicit    ...

  7. 网上图书商城2--Category模块

    sql CREATE TABLE `t_category` ( `cid` char(32) NOT NULL, `cname` varchar(50) DEFAULT NULL, `pid` cha ...

  8. PDF.NET 开发框架之 SOD框架 Ver 5.2 正式版开源源码发布

    PDF.NET 开发框架之 SOD框架 Ver 5.2.1.0307 正式版发布,包含以下部分: SOD_Pwmis.Core --包括下列数据提供程序 SqlServer SqlServerCe A ...

  9. 简单可用好实现的 HA 高可用设计

    本文为作者原创,如需转载请注明出处. 1. 实现的功能 一主多备,自动选主 启动记录可查询 2. 前置需求 一台数据库用以记录,如 MySQL.Redis.MongoDB 等.关键是设计中的思想,用啥 ...

  10. 深入源码分析使用jQuery连续发起jsonp请求失败的原因

    jQuery的 jsonp 大家应该是十分熟悉了.曾遇到过这样的需求1.希望请求几个相似的内容添加到页面2.请求的内容一定时间内是固定不变的,希望做个缓存. 于是脑子一拍写下了类似这样的代码 for( ...