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)
JavaScript Patterns 7.1 Singleton的更多相关文章
- JavaScript Patterns 6.7 Borrowing Methods
Scenario You want to use just the methods you like, without inheriting all the other methods that yo ...
- JavaScript Patterns 6.6 Mix-ins
Loop through arguments and copy every property of every object passed to the function. And the resul ...
- JavaScript Patterns 6.5 Inheritance by Copying Properties
Shallow copy pattern function extend(parent, child) { var i; child = child || {}; for (i in parent) ...
- JavaScript Patterns 6.4 Prototypal Inheritance
No classes involved; Objects inherit from other objects. Use an empty temporary constructor function ...
- JavaScript Patterns 6.3 Klass
Commonalities • There’s a convention on how to name a method, which is to be considered the construc ...
- JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance
// the parent constructor function Parent(name) { this.name = name || 'Adam'; } // adding functional ...
- 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 ...
- JavaScript Patterns 5.9 method() Method
Advantage Avoid re-created instance method to this inside of the constructor. method() implementatio ...
- JavaScript Patterns 5.8 Chaining Pattern
Chaining Pattern - Call methods on an object one after the other without assigning the return values ...
随机推荐
- Redis系列一之数据结构
一.Redis简介 redis是一个高性能的key-value非关系数据库,它可以存键(key)与5种不同类型的值(value)之间的映射(mapping),支持存储的value类型包括:String ...
- 关于在Servelet中如何获取当前时间的操作
//获取到当前时间 Date date=new Date(); DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss&quo ...
- Android使用SQLite数据库(2)
打开SQLite数据库,首先要建立一个DatabaseHelper类的实例,然后,再获得数据库: DatabaseHelper mDBH; SQLiteDatabase db; mDBH = new ...
- Facebook的Hack语言三大看点
Hack语言主要有三大看点:类型化.异步.集合. Hack最基础的特性就是类型标注.PHP5已经开始支持对象的类型化,PHP7也提供了标量类型化声明.Hack提供了全面的类型标注支持,与其typech ...
- 泛函编程(33)-泛函IO:Free Functor - Coyoneda
在前几期讨论中我们终于推导出了Free Monad.这是一个Monad工厂,它可以把任何F[A]变成Monad.可惜的是它对F[A]是有所要求的:F必须是个Functor.Free Monad由此被称 ...
- Windows Git中文文件名乱码
在Windows下使用git,安装包如下: https://git-for-windows.github.io/ 在使用git bash时git 默认中文文件名是 xx% 是因为 对0x80以上的字符 ...
- 指针,&的用法
#include "stdafx.h" #include <stdio.h> #include <string.h> int main() { ] = {, ...
- sql2000新建登陆用户错误“21002:[SQL-DMO] 用户***已经存在”的原因和解决方法【孤立用户解决方法】
错误症状: 在SQL Server200中用附加数据库导入数据后,在新建登录时出现会出现错误21002:[SQL-DMO] 用户***已经存在.然后发现没建成的用户已经在登录列表里了.删除重建,问题依 ...
- Android 手机卫士4--设置中心显示
1,自定义属性 SettingActivity.java package com.itheima.mobilesafe74.activity; import com.itheima.mobilesaf ...
- [Cordova] 无法编译Visual Studio项目里Plugin副本的Native Code
[Cordova] 无法编译Visual Studio项目里Plugin副本的Native Code 问题情景 开发Cordova Plugin的时候,开发的流程应该是: 建立Cordova Plug ...