Typescript泛型单例-支持继承,使用方便

1、Singleton.ts

export function Singleton<E>() {
    class SingletonE {
        protected constructor() {}
        private static _inst: SingletonE = null;
        public static get inst(): E {
            if(SingletonE._inst == null) {
                SingletonE._inst = new this();
            }
            return SingletonE._inst as E;
        }
    }

    return SingletonE;
}

2、Test.ts

class Test extends Singleton<Test>() {
    abc = 0;
    cocos() {
    }
}

3、使用

Test.inst.abc;
Test.inst.cocos();
7赞

额,这个继承单例已经发过了https://forum.cocos.org/t/muzzik/96045/3

还有不能用get,否则构造不能带参

你这么写我其实有点是看不懂的 不是有泛型类? 但是我写泛型类的会报错. 而且你这个代码我试了也没提示? 写法看来还是不行

因为要用到static 必须还是要写在本类中 算了,研究不出来用继承该怎么写 直接复制就完事 就4行代码 你这样写没提示还继承多一个类真的蛋疼啊

你怎么写的。我这边都是有提示的。

为什么要构造带参?

我就是直接复制 试了没提示啊

我用的vscode是有提示的- -

你这个问题本来就很奇怪

可能是想要传参吧 我单例都不用传参

哪里奇怪,你的才奇怪。

如果在代码的多个位置想要获取单例,且根据获取位置的不同初始化不同的数据,那么请问宁怎么做呢?再写个函数手动调用?我还是第一次见到有人用自己的接口封杀了语言特性还认为自己是对的

再写个函数不是不可以, 初始化不同的数据这还是单例? 一个设计模式可不是这么用的吧

构造里能做到的事,非得另外写个初始化函数,再手动调用一次,你喜欢这样写那就这样吧,至于用法每个人都有每个人的用法,你用不到就不代表别人用不到,你不用就不表示别人也不能用,用api封锁语言特性本就是错误的处理,既然你们愿意这样做,那我就只好祝你们在这条路上越走越远了

无聊。。。

你觉得你的写法很好, 但这样写不是最好的 你那个单例写法我也看过了 之前我也是想那么写 但始终觉得不是最好的写法. 我现在的单例是game_模块名 初始化函数对于数据初始化是必需的, 直接放构造函数 你的代码被人看了肯定要被吐槽, 因为不知道要初始化有多少数据, 交给初始化函数, 释放构造函数 通俗易懂

对于数据的初始化,只需要初始化一次,对于视图的初始化也只需要初始化一次,相应的是视图的重置和刷新,这才是需要多次调用的地方,对于只执行一次任务的初始化而言,把数据初始化写在一个单独的函数并没有任何意义,而视图初始化也只需要放在onload或者onstart,难道还在这里面来写一行init()?多增加一次入栈出栈?至于吐槽,这得看别人对于代码架构和项目组件的概念理解了

不仅是init如果需要初始化过多还分ui 和数据 单单几行代码还是直接放就好了, init相当初始化所有的, 不然再调用一次onLoad?

我自己实现两种
A 方案:
export default class BaseSigleton{ static get i() { if(!this._i)this._i = new this(); return this._i; } private static _i; }
B 方案:

export default class BaseSigleton{ static i<T extends {}>(this: new () => T): T { if(!(<any>this)._i){ (<any>this)._i = new this(); } return (<any>this)._i; } private static _i; }

继承

`import BaseSigleton from “./BaseSigleton”;

export default class TestChild extends BaseSigleton{
say(){
console.log("----:", JSON.stringify(“Hello”));
}
}`

调用方法:
A 方案:
TestChild.i.say()
B方案:
TestChild.i().say()

结果输出:

----: "Hello"

个人感觉 更喜欢 A方案 无括号的版本
B方案应该是比较经典的 单例方法