ts 实现

  • 私有变量
  • 私有构造函数 不允许在外部通过 new 创建实例
  • 提供获取实例的方法
export class Singleton {
// 私有变量
private static instance: Singleton;
public options: {};
// 私有构造函数
private constructor(options) {
this.options = options;
}

// 获取实例的方法
public static getInstance(options): Singleton {
//第二次就不会进入判断
if (!Singleton.instance) {
Singleton.instance = new Singleton(options);
}
return Singleton.instance;
}
//判定是否以及初始化
public isInitialized(): boolean {
return !!Singleton.instance;
}
}

js 实现

class Singleton {
// instance = undefined;
constructor(name) {
console.log("实例化");
}
// static getInstance(name) {
// if (!this.instance) {
// this.instance = new Singleton(name);
// }
// return this.instance;
// }
// getName() {
// console.log(this.name);
// }
}

// const instance1 =Singleton.getInstance("王五");
// const instance2 = Singleton.getInstance("李四");
// const instance3 = new Singleton("王五");
// console.log("instance1 === instance2:", instance1 === instance2); //true
// console.log("instance1 === instance3:", instance1 === instance3); //false

//无法阻止通过new操作符创建新实例
//那么我就代理这个类,在代理类中判断如果实例已经存在,就返回这个实例,否则创建实例

function CreateSingleton(className) {
//用于判定是否为初次实例化
let instance = null;
const proxy = new Proxy(className, {
construct(target, args) {
//如果实例已经存在,就返回这个实例
console.log("inside proxy constructor", instance);
if (!instance) {
instance = Reflect.construct(target, args);
}
return instance;
},
});
//防止套娃,把类的构造函数指向代理类
className.prototype.constructor = proxy;
return proxy;
}
const MySingleton = new CreateSingleton(Singleton);
const s = new MySingleton();
const s1 = new MySingleton();
//运行时 s is not a constructor
const s2 = new s();
console.log(s === s1);