原文:https://segmentfault.com/a/1190000012842251
定义
单例模式使用的场景
比如线程池、全局缓存等。我们所熟知的浏览器的window对象就是一个单例,在JavaScript开发中,对于这种只需要一个的对象,我们的实现往往使用单例。
实现单例模式 (不透明的)
一般我们是这样实现单例的,用一个变量来标志当前的类已经创建过对象,如果下次获取当前类的实例时,直接返回之前创建的对象即可。代码如下:
// 定义一个类
function Singleton(name) {
this.name = name;
this.instance = null;
}
// 原型扩展类的一个方法getName()
Singleton.prototype.getName = function() {
console.log(this.name)
};
// 获取类的实例
Singleton.getInstance = function(name) {
if(!this.instance) {
this.instance = new Singleton(name);
}
return this.instance
};
// 获取对象1
var a = Singleton.getInstance('a');
// 获取对象2
var b = Singleton.getInstance('b');
// 进行比较
console.log(a === b);
我们也可以使用闭包来实现:
function Singleton(name) {
this.name = name;
}
// 原型扩展类的一个方法getName()
Singleton.prototype.getName = function() {
console.log(this.name)
};
// 获取类的实例
Singleton.getInstance = (function() {
var instance = null;
return function(name) {
if(!this.instance) {
this.instance = new Singleton(name);
}
return this.instance
}
})();
// 获取对象1
var a = Singleton.getInstance('a');
// 获取对象2
var b = Singleton.getInstance('b');
// 进行比较
console.log(a === b);
知识点总结:
getInstance是类的静态方法,它里面的this指向类。类构造函数或者实例方法或者原型链上方法里的this指向类的实例。
function Singleton(name) {
this.name = name;
}
// 原型扩展类的一个方法getName()
Singleton.prototype.getName = function() {
console.log(this.name)
};
// 获取类的实例
Singleton.getInstance = (function(){
var instance = null;
return function (name) {
if(!this.instance) {
this.instance = new Singleton(name);
}
return this.instance;
}
})()
// 获取对象1
var a = Singleton.getInstance('a');
// 获取对象2
var b = Singleton.getInstance('b');
// 进行比较
console.log(a === b);
这个单例实现获取对象的方式经常见于新手的写法,这种方式获取对象虽然简单,但是这种实现方式不透明。知道的人可以通过 Singleton.getInstance()
获取对象,不知道的需要研究代码的实现,这样不好。这与我们常见的用 new
关键字来获取对象有出入,实际意义不大。
**