单例模式
amandakelake opened this issue · 2 comments
amandakelake commented
定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点
特性
系统中被唯一使用
一个类只有一个实例
实例
- 登录框
- 购物车
- redux、vuex中的store
特别说明
单例模式没有private属性(java的特性)
ES6没有,TS除外
只能用Java代码来演示
用JS模拟java的单例
class SingleObject {
login() {
console.log("login")
}
}
// 通过给类挂载一个静态方法,而且是自执行方法
// 通过闭包,返回唯一的实例instance
// 实例只有一个
SingleObject.getInstance = (function() {
let instance;
// 返回一个函数
return function() {
if (!instance) {
instance = new SingleObject();
}
return instance
}
})()
let obj1 = SingleObject.getInstance();
let obj2 = SingleObject.getInstance();
obj1.login();
obj2.login();
// 这里会返回true,说明是唯一的同一个实例
console.log('obj1 === obj2', obj1 === obj2);
// 但是,这里只能口头约定不能直接new SingleObject()
// 就算new了,也不会报错,下面会返回false
let obj3 = new SingleObject()
console.log('obj1 === obj3', obj1 === obj2);
jquery模拟了单例的**,只有一个$
if (window.jQuery != null) {
return window.jQuery
} else {
// 初始化
}
存在的问题
1,违反了单一职责原则
2、每次都会创建新的实例(可以做成惰性)
惰性单例
// 职责单一,不干涉fn的逻辑
const getSingle = function(fn) {
// 闭包大兄弟,用来保存fn函数执行后的计算结果
let result;
return function() {
return result || (result = fn.apply(this, arguments));
}
}
// 模拟一个fn 生成一个iframe/div/script
const createIframe = function() {
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
return iframe;
}
// 结合使用 创建唯一实例对象
const singleIframe = getSingle(createIframe);
ycai2 commented
代码对的 不过单例在英文中正确的叫法是Singleton哦
amandakelake commented
@ycai2 好的哈 感谢大兄弟