保证一个类仅有一个实例,并提供一个访问它的全局访问点。
如何实现
实现单例模式无非是用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象。
- 第一种方法
var Singleton = function (name) {
this.name = name;
this.instance = null;
};
Singleton.prototype.getName = function () {
console.log(this.name);
};
Singleton.getInstance = function (name) {
if (!this.instance) {
this.instance = new Singleton(name);
}
return this.instance;
};
let test1 = Singleton.getInstance('name1');
let test2 = Singleton.getInstance('name2');
console.log(test1 == test2);
- 第二种方法
var Singleton = function (name) {
this.name = name;
};
Singleton.prototype.getName = function () {
console.log(this.name);
};
Singleton.getInstance = (function () {
// 使用匿名函数闭包防止全局变量的污染
let instance = null;
return function (name) {
if (!instance) {
instance = new Singleton(name);
}
return instance;
};
})();
let test1 = Singleton.getInstance('name1');
let test2 = Singleton.getInstance('name2');
console.log(test1 == test2);
JavaScript 中的单例模式
核心是确保只有一个实例,并提供全局访问。全局变量不是单例模式,在 js 中我们经常把全局变量当成单例使用。
避免全局变量
- 使用命名空间
var Myapp = {};
Myapp.namespace = function (name) {};
Myapp.namespace('event');
// 以上代码等同于如下代码
var MyApp = {
event: {},
};
- 使用闭包封装私有变量
var user = (function () {
var _name;
return {
getUserInfo() {
return _name;
},
};
})();
惰性单例
实例对象总是在我们调用的时候才被创建,而不是在加载好的时候创建。
// 单例模式的实现
var getSingle = function (fn) {
var result;
return function () {
return result || (result = fn.apply(this, arguments));
};
};
// 弹窗测试
var createLoginLayer = function () {
var div = document.createElement('div');
div.innerHTML = '我是浮窗';
div.style.display = 'none';
document.body.appendChild(div);
return div;
};
var createSingleLoginLayer = getSingle(createLoginLayer);
document.getElementById('loginBtn').onclick = function () {
var loginLayer = createSingleLoginLayer();
loginLayer.style.display = 'block';
};
// ifame测试
var createSingleIframe = getSingle(function () {
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
return iframe;
});
document.getElementById('loginBtn').onclick = function () {
var loginLayer = createSingleIframe();
loginLayer.src = 'http://blog.niumingxin.com/';
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。