JavaScript单例模式的三种实现
2023-12-28 21:45:16
单例模式
????????单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。
实现单例
方式一?
//创建单例
class SingleTon {
//添加静态私有属性
static #instanse;
//添加静态方法
static getInstanse() {
//判断静态私有属性内是否有实例,如果没有就创建一个并返回,如果有就直接返回
if (this.#instanse === undefined) {
this.#instanse = new SingleTon();
}
return this.#instanse;
}
}
const sing1 = SingleTon.getInstanse();
const sing2 = SingleTon.getInstanse();
console.log(sing1 === sing2); //true
最简单的方式就是希望别人通过 SingleTon.getInstanse()的方式来获得一个实例。但是这种方法不能保证别人不去new一个,这样就不能保证单例了
const sing1 = SingleTon.getInstanse();
const sing2 = new SingleTon();
console.log(sing1 === sing2); //false
?方式二
ES6新增了模块化,那我直接导出创建的实例,不就能解决问题了吗?我们来看看是否能达到目的。?
//创建单例
class SingleTon {
//添加静态私有属性
static #instanse;
//添加静态方法
static getInstanse() {
//判断静态私有属性内是否有实例,如果没有就创建一个并返回,如果有就直接返回
if (this.#instanse === undefined) {
this.#instanse = new SingleTon();
}
return this.#instanse;
}
}
export default SingleTon.getInstanse();
看起来好像没什么问题,但此处还存在隐患,导出的实例对象可以通过?constructor找到其构造函数,构造函数都找到了,不也可以直接new一个新的实例化对象吗?
<script type="module">
import v from "./SingleTon.js";
const v2 = new v.constructor();
console.log(v2 === v); //false
</script>
方式三?
通过代理实现单例?
//创建单例
class SingleTon {
//添加静态私有属性
static #instanse;
//添加静态方法
static getInstanse() {
//判断静态私有属性内是否有实例,如果没有就创建一个并返回,如果有就直接返回
if (this.#instanse === undefined) {
this.#instanse = new SingleTon();
}
return this.#instanse;
}
}
//传入一个构造函数,返回一个代理
function SingleTonfn(targetConstructor) {
let ins = null;
const proxy = new Proxy(targetConstructor, {
construct(target, args) {
if (!ins) ins = new targetConstructor(...args);
return ins;
},
});
targetConstructor.prototype.constructor = proxy; //将其原型的指向 指为proxy
return proxy;
}
const v = SingleTonfn(SingleTon);
const v1 = new v();
const v2 = new v();
const v3 = new v1.constructor();
console.log(v1 === v2); //true
console.log(v1 === v3); //true
文章来源:https://blog.csdn.net/m0_53062068/article/details/135206962
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!