单例模式
单例就是确保一个类只有一个实例,任何时候调用的实例都是同一个,这个实例只会初始化一次。
方式一
实现步骤:
- 最简单的——对象字面量的方式
其字面量里可以包含大量的属性和方法,直接创建好的单例对象。这样创建的对象变量全局化了,
var instance={
prop1: "prop1",
prop2: "prop2",
method1: function () {
console.log('hello world');
}
}
- 扩展该单例对象可以添加自己的私有变量和方法,只暴露公有变量和方法方式,通过闭包的方式来实现。
var mySingleton = function(){
// 私有变量和方法
var priv_prop='private prop';
var priv_mtd = function(){
console.log(priv_prop)
}
// 公有变量和方法,能访问私有变量和方法
return {
pub_mtd: function(){
priv_mtd()
},
pub_prop: 'public prop'
}
}
var instance = mySingleton();
instance.pub_mtd(); // 输出 'private prop'
console.log(instance.pub_prop); // 输出 'public prop'
事实上这里的mySingleton()并不是单例的,只是在第一步上做了扩展可以访问私有变量
var instance2 = mySingleton();
instance === instance2 //false
- 真正的创建实例,每次调用的都是同一个对象实例,第一调用才会初始化。
var Singleton = (function(){
// 这里定义单例代码
var instance;
function init(){
return {
pub_mtd: function(){
console.log('this is pub_mtd');
},
pub_prop:'this is pub_prop'
}
};
return {
getInstance:function(){
if (!instance){
instance = init()
}
return instance
}
}
})()
/*调用公有的方法的时候初始化实例:*/
Singleton.getInstance().pub_mtd();
let a=Singleton.getInstance();
let b=Singleton.getInstance();
a === b // true 此时才算是真正的单例
a.pub_mtd === b.pub_mtd //true
a.pub_mtd() //打印出'this is pub_mtd';
此时才算是真正的单例,任何时候调用Singleton.getInstance()都是同一个实例。
其他实现方式
方法1-通过重写构造函数直接调用前一次生成的实例
function Instance(){
var instance = this;
console.log(111)
this.prop='prop';
this.mtd=function(){
console.log(this.prop);
}
//重写构造函数
Instance = function(){
console.log(222)
return instance;
}
}
var a = new Instance() // 打印出111,同时构造函数被重写,
var b = new Instance() // 打印出222,直接返回前一次调用缓存的instance
a === b // true
方法2-把首次生成的实例缓存到构造函数的属性上
function Instance(){
if (typeof Instance.instance === 'object'){
return Instance.instance
}
this.prop='prop';
this.mtd=function(){
console.log(this.prop);
};
// 缓存
Instance.instance=this;
// 隐式返回 this
}
var ins1=new Instance();
var ins2=new Instance();
ins1 === ins2
方法3-内部重写构造函数,修改原型属性,重设构造函数指针
function Instance(){
var instance;
console.log(1)
// 二次调用的构造函数
Instance = function Instance(){
console.log(2)
return instance;
};
console.log(3)
// 后期处理原型属性
Instance.prototype = this;
// 实例
instance = new Instance();
console.log(4)
// 重设构造函数指针
instance.constructor = Instance;
instance.prop='prop';
instance.mtd=function(){
console.log(instance.prop)
}
console.log(5)
return instance
}
var a = new Instance();
// 13245
var b = new Instance();
// 2