var mySingleton = (function () {
// Instance stores a reference to the Singleton
var instance;
function init() {
// Singleton
// Private methods and variables
function privateMethod(){
console.log( "I am private" );
}
var privateVariable = "Im also private";
var privateRandomNumber = Math.random();
return {
// Public methods and variables
publicMethod: function () {
console.log( "The public can see me!" );
},
publicProperty: "I am also public",
getRandomNumber: function() {
return privateRandomNumber;
}
};
}
return function(){
// Get the Singleton instance if one exists
// or create one if it doesn't
if ( !instance ) {
instance = init();
}
return instance;
};
})();
var myBadSingleton = (function () {
// Instance stores a reference to the Singleton
var instance;
function init() {
// Singleton
var privateRandomNumber = Math.random();
return {
getRandomNumber: function() {
return privateRandomNumber;
}
};
}
return {
// Always create a new Singleton instance
getInstance: function () {
instance = new init();
return instance;
}
};
})();
// Usage:
var singleA = mySingleton();
var singleB = mySingleton();
console.log( singleA.getRandomNumber() === singleB.getRandomNumber() ); // true
var badSingleA = myBadSingleton.getInstance();
var badSingleB = myBadSingleton.getInstance();
console.log( badSingleA.getRandomNumber() !== badSingleB.getRandomNumber() ); // true
// Note: as we are working with random numbers, there is a
// mathematical possibility both numbers will be the same,
// however unlikely. The above example should otherwise still
// be valid.
// 这里还有一个缺点:客户端使用时候需要特别注明(研究代码)才知道getInstance是唯一的访问入口,而MyBadSingleton只需要调用函数就可以获取单例
}
知识点二:一个单例必须要符合以下两点
该类只能有个一个实例,客户端只能够通过一个众所周知的访问入口访问
该实例可以通过子类扩展,客户端应该无需更改任何代码就可以使用该子类扩展的实例
知识点三: 单例扩展
针对第二点,上面例子getInstance更改为
class BasicSingleton {
// ...
}
class FooSingleton extends BasicSingleton {
// ...
}
var mySingleton = (function () {
var instance;
function isFoo() {
// ...
}
return function () {
if ( instance == null ) {
if ( isFoo() ) {
instance = new FooSingleton();
} else {
instance = new BasicSingleton();
}
}
return instance;
}
})();