JS代理实现单例模式
JS设计模式之单例模式
单例模式--保证一个类仅有一个单例
1. 简单单例模式
// 简单单例模式
const Singleton = function (name) {
this.name = name;
};
Singleton.instance = null;
Singleton.getInstance = function (name) {
if (!Singleton.instance) {
Singleton.instance = new Singleton(name);
}
return Singleton.instance;
};
const s1 = Singleton.getInstance("xiaxiang");
const s2 = Singleton.getInstance();
console.log(s1, s2, s1 === s2);

这种方式相对简单, 缺点是使用者必须知道这个类有获取单例方法
2. 透明单例方法
让使用者像平常一样, new出来的对象永远都是相同的一个
// 透明单例模式
function Singleton(name) {
let instance = Singleton.instance;
if (!instance) {
Singleton.instance = {};
instance = Singleton.instance;
}
instance.name = name;
return instance;
}
const single1 = new Singleton("xiaxiang");
const single2 = new Singleton("xiaowai");
console.log(single1, single2, single2 === single1);
// true
其实 new 出来的对象就是该方法返回的对象, 以往返回默认的是 this, 现在显式返回方法静态属性, 从而实现单例效果.
该方法让单例化透明, 同时也让这个类无法扩展, 只能是单例, 若日后有更改需求, 十分麻烦, 这时候可以采用代理模式
3. 完美代理模式
function Singleton(name) {
this.name = name;
}
const SingletonProxy = new Proxy(Singleton, {
construct(target, args) {
if (!SingletonProxy.instance) {
SingletonProxy.instance = new Singleton(args);
return SingletonProxy.instance;
} else {
return SingletonProxy.instance;
}
},
});
const single1 = new SingletonProxy("xia");
const single2 = new SingletonProxy("xiao");
console.log(single1, single2, single1 === single2);

优点
- 将定义类与使用类解耦, 对原有类没有产生任何影响
- 实现了懒加载, 只有当第一次使用单例代理时才会创建单例对象
4. 补充
const namespace1 = {
get a() {
return 1;
},
set a(value) {
a = value;
},
};
console.log((namespace1.a = 2));
使用 get set 方法控制对象属性的访问设置
单例模式可以使用类也可以直接使用对象, 具体视情况而定
希望读者在看完后能提出意见, 点个赞, 鼓励一下, 我们一起进步. 加油 !!

浙公网安备 33010602011771号