静态成员

前面所定义的类的成员都是动态成员,它们属于类的实例,只有在实例化该类的具体对象后才能使用这些成员。在 TypeScript 中,还可以为类定义静态成员,它们不属于类的实例,而属于类本身,需要通过类的名称直接访问这些成员。

静态成员的声明与访问

TypeScript 中,使用 static 定义静态成员,静态成员只能通过 “类名称.成员名称” 的形式访问。

例如,以下代码声明了一个 Logger 类,它拥有一个静态属性 version 和一个静态方法 writeLog()。无须实例化该类,直接通过类名的形式就可以使用这些成员,如 Logger.versionLogger.writeLog

class Logger {
    static version = "1.0";
    static writeLog(logContent: any) {
        console.log(logContent);
    }
}

console.log(Logger.version);      //输出1.0
Logger.version = "2.0";
Logger.writeLog("error occars."); //输出error occars

由于静态成员属于类本身,并不属于类的实例,因此无法通过实例化该类后产生的对象访问这些静态成员。例如,以下代码将引起编译错误。

let logger = new Logger();
//编译错误:属性"version"在类型"Logger"上不存在。你的意思是改为访问静态成员
// "Logger.version"吗?ts(2576)
logger.version = "3.0";
//编译错误:属性"writeLog"在类型"Logger"上不存在。你的意思是改为访问静态成员
// "Logger.writeLog"吗?ts(2576)
logger.writeLog("this is a log");

也可以使用 publicprotectedprivate 等关键字控制静态成员的可访问性,这里不再讲述。

静态成员的继承

与动态成员类似,静态成员也可以继承,子类将继承父类的除 private 级别的成员以外的所有静态成员。

例如,在以下代码中,Logger 类的两个静态成员都可以由 DBLogger 继承,然后再通过子类的名称使用这些静态成员,如 DBLogger.versionDBLogger.writeLog

class Logger {
    static version = "1.0";
    static writeLog(logContent: any) {
        console.log(logContent);
    }
}

class DBLogger extends Logger { }

console.log(DBLogger.version);     //输出1.0
DBLogger.writeLog("error occars.") //输出"error occars."

注意,如果更改父类的静态属性,那么子类的静态属性也将一并更改;而如果更改子类的静态属性,父类的静态属性不受影响。例如,以下代码先将 Logger 类的 version 属性更改为 2.0,DBLogger 类的 version 属性也会变为 2.0,如果更改 DBLogger 类的 version 属性为 3.0,Logger 类的 version 属性依然为 2.0。

Logger.version = "2.0";
console.log(Logger.version);   //输出2.0
console.log(DBLogger.version); //输出2.0

DBLogger.version = "3.0";
console.log(Logger.version);   //输出2.0
console.log(DBLogger.version); //输出3.0

静态代码块

由于静态成员的使用并不需要实例化该类,因此构造函数无法用于初始化静态成员。如果要初始化静态成员的值,先简单赋值然后直接使用默认值即可。不过,对于初始化计算较复杂的情况,就需要借助静态代码块。

静态代码块以 “static { 代码块 }” 的形式定义,它将会在首次使用静态成员之前执行,且只执行一次。

例如,以下代码声明了一个 ThreadClass 类,它拥有一个静态属性 maxThreadCountmaxThreadCount 属性根据允许的平台而不同,因此这里定义了一个静态代码块,根据当前运行代码的平台是 Node.js 还是浏览器,决定 maxThreadCount 属性的初始值。最后一句输出了 maxThreadCount 属性的值,在 Node.js 环境下输出值为 10,在浏览器环境下输出值为 1。

class ThreadClass {
    static maxThreadCount: number;
    static {
        if (globalThis.toString() == "[object Window]")
            ThreadClass.maxThreadCount = 1;
        else
            ThreadClass.maxThreadCount = 10;
    }
}

//以下代码在Node.js环境下将输出10,在浏览器环境下将输出1
console.log(ThreadClass.maxThreadCount);