前言:菜鸡也有梦想,而我的梦想就是进一个真正的互联网大厂。以前学习的时候没有系统的整理,从今天开始要保持每周写博客的习惯,希望自己可以有所成长。为了培养编程思维,决定从设计模式开始写起。我是通过读《Javascript设计模式与开发实践》来学习设计模式,并且将知识点和收获记录在博客中。
此文仅记录本人阅读《JavaScript设计模式与开发实践》的知识点与想法,感谢作者曾探大大写出这么好的一本书。如有冒犯,请联系本人:markcoder@outlook.com处理,请大家购买正版书籍。
1. 单例模式介绍
单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
比如登录框和购物车就适合用单例模式。
2.代码实现
要点:用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象。
const Singleton = function (name) {
this.name = name;
this.instance = null;
};
Singleton.prototype.getName = function () {
alert(this.name);
};
Singleton.getInstance = function (name) {
if (!this.instance) { // 如果之前没有创建过实例
this.instance = new Singleton(name);
}
return this.instance;
};
let a = Singleton.getInstance('event1');
let b = Singleton.getInstance('event2');
console.log(a === b); // true
或者
const Singleton = function (name) {
this.name = name;
};
Singleton.prototype.getName = function () {
alert(this.name);
};
Singleton.getInstance = (function () {
let instance = null;
return function (name) {
if (!instance) { // 如果之前没有创建过实例
instance = new Singleton(name);
}
return instance;
}
})();
let a = Singleton.getInstance('event1');
let b = Singleton.getInstance('event2');
console.log(a === b); // true
ES6实现
class Singleton {
login () {
console.log(login)
}
}
Singleton.getInstance = (function () {
let instance;
return function () {
if (!instance) {
instance = new Singleton();
}
return instance;
}
})();
let a = Singleton.getInstance();
let b = Singleton.getInstance();
console.log(a === b); // true
Singleton类的使用者必须知道通过 Singleton.getInstance 这个方法来获取对象,而不是通过 new XXX 的方式。
3.透明的单例模式
let CreateDiv = (function () {
let instance;
let CreateDiv = function (html) {
if (instance) {
return instance;
}
this.html = html;
this.init();
return instance = this;
};
CreateDiv.prototype.init = function () {
let div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
};
return CreateDiv; // 返回真正的构造方法
})();
let a = new CreateDiv( 'event1' );
let b = new CreateDiv( 'event2' );
console.log ( a === b ); // true
通过匿名函数返回真正的构造函数 CreateDiv 。假如某天我们要在页面中创建更多的div,就需要修改构造函数,所以代码仍然需要改进。
4.用代理实现单例模式
let CreateDiv = function (html) {
this.html = html;
this.init();
};
CreateDiv.prototype.init = function () {
let div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
};
// 利用闭包将管理单例模式的逻辑放在了proxySingleton
let proxySingleton = (function () {
var instance;
return function (html) {
if (!instance) {
instance = new CreateDiv(html);
}
return instance;
}
})();
let a = new proxySingleton( 'sven1' );
let b = new proxySingleton( 'sven2' );
console.log ( a === b );
5.使用单例模式的总结
- 模拟登录框
class Login {
constructor () {
this.state = 'hide'
}
show () {
if (this.state === 'show') {
return
}
this.state = 'show'
}
hide () {
if (this.state === 'hide') {
return
}
this.state = 'hide'
}
}
Login.getInstance = (function () {
let instance;
return function () {
if (!instance) {
instance = new Login();
}
return instance
}
})();
let login1 = Login.getInstance();
let login2 = Login.getInstance();
console.log(login1 === login2);
- 无论引入多少次jQuery库,全局只有一个$
if (window.jQuery != null) {
return window.jQuery
} else {
// 初始化
}
- vuex和redux的store