Javascript 如何创建一个不能在TypeScript外部实例化的类?

Javascript 如何创建一个不能在TypeScript外部实例化的类?,javascript,typescript,Javascript,Typescript,在Java中,我们有私有构造函数 public class Singleton{ private static volatile Singleton INSTANCE = null; private Singleton(){ } public static Singleton getInstance(){ if(INSTANCE == null){ synchronized(Singleton.class){

在Java中,我们有私有构造函数

public class Singleton{
    private static volatile Singleton INSTANCE = null;
    private Singleton(){ }

    public static Singleton getInstance(){
        if(INSTANCE == null){
            synchronized(Singleton.class){
                if(INSTANCE == null){
                    INSTANCE = new Singleton();
                }
            }
        }
    return INSTANCE;
    }
}

这使得课堂不能在课外进行。TypeScript中有类似的东西吗?

类似的东西应该可以:

class Singleton {

    private static _instance:Singleton = new Singleton();

    constructor() {
        if (Singleton._instance){
            throw new Error("Error: use getInstance()");
        }
        Singleton._instance = this;
    }

    public static getInstance():Singleton {
        return Singleton._instance;
    }

    ...
 }
另外,在java中,不需要使用延迟初始化,因为如果不使用单例,则不会初始化单例。更好的方法:

public class Singleton {
    private static Singleton INSTANCE = new Singleton();
    private Singleton() {}

    public Singleton getInstance(){
        return INSTANCE;
    }
}
class MySingleton {
    private static volatile MySingleton instance;

    private MySingleton() {
        // do what ever
    }

    public static MySingleton getInstance() {
        if (MySingleton.instance == null) {
            synchronized (MySingleton.class) {
                if (MySingleton.instance == null) {
                    MySingleton.instance = new MySingleton();
                }
            }
        }

        return MySingleton.instance;
    }
}
为了回答智鹏的评论,静态初始化是线程安全的,如JLS中的定义:

Java虚拟机的实现负责使用以下过程进行同步和递归初始化

注意:只有在可以使用某些静态方法而不使用getInstance时,使用惰性实现才有用。在这种情况下,如果从未使用过,也会实例化Singleton类

有关java上的Singleton的完整描述,请参阅我为

撰写的一篇文章,了解如何实现这一点,但请注意,TypeScript 2.0将具有私有构造函数,并且很快就会发布。目前,我建议编写以下代码

class Singleton {
    private static instance: Singleton = new Singleton();

    // todo: mark as private when TS 2.0 comes out
    constructor() {
    }

    static getInstance() {
        return this.instance;
    }
}

…然后在TypeScript 2.0发布后将其更改为private。

我将从java部分开始,并将在@DavidorenZomarino编写的内容上添加一个额外的内容,即:

如果你真的想确保它在多线程环境中工作,那么你甚至可能要考虑这样的方法:

public class Singleton {
    private static Singleton INSTANCE = new Singleton();
    private Singleton() {}

    public Singleton getInstance(){
        return INSTANCE;
    }
}
class MySingleton {
    private static volatile MySingleton instance;

    private MySingleton() {
        // do what ever
    }

    public static MySingleton getInstance() {
        if (MySingleton.instance == null) {
            synchronized (MySingleton.class) {
                if (MySingleton.instance == null) {
                    MySingleton.instance = new MySingleton();
                }
            }
        }

        return MySingleton.instance;
    }
}
至于typescript部分,我认为这个模式在typescript中并不好用,因为与java在运行时不同,没有什么可以阻止另一个开发人员实例化多个实例

如果您信任使用代码的开发人员,那么这很好,但是如果不信任,那么为什么不将实例包围在模块/命名空间中,以便隐藏实现呢

比如:

namespace MySingleton {
    class MySingletonInstance {
        echo(value: string): string {
            console.log(value);
            return value;
        }
    }

    export var instance = new MySingletonInstance();
}
但是,由于这个类只有一个实例,因此我认为在javascript中,完全不使用类更有意义,它只会使事情变得更加冗长,您可以简单地:

namespace MySingleton {
    export interface MySingletonInstance {
        echo(value: string): string;
    }

    export var instance: MySingletonInstance = {
        echo: value => {
            console.log(value);
            return value;
        }
    }
}

但是,如果单例是在Java的多线程环境中呢?它会崩溃吗?静态初始化是线程安全的,这是由designI授予的。我在官方文档中添加了一个链接,解释静态初始化器是如何线程安全的。谢谢。TypeScript中的另一个问题:因为在构造函数中,它将抛出异常。那么,在使用新的Singleton调用它时,它会导致问题吗?