静态成员
前面所定义的类的成员都是动态成员,它们属于类的实例,只有在实例化该类的具体对象后才能使用这些成员。在 TypeScript 中,还可以为类定义静态成员,它们不属于类的实例,而属于类本身,需要通过类的名称直接访问这些成员。
静态成员的声明与访问
在 TypeScript 中,使用 static
定义静态成员,静态成员只能通过 “类名称.成员名称” 的形式访问。
例如,以下代码声明了一个 Logger
类,它拥有一个静态属性 version
和一个静态方法 writeLog()
。无须实例化该类,直接通过类名的形式就可以使用这些成员,如 Logger.version
和 Logger.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");
也可以使用 public
、protected
、private
等关键字控制静态成员的可访问性,这里不再讲述。
静态成员的继承
与动态成员类似,静态成员也可以继承,子类将继承父类的除 private
级别的成员以外的所有静态成员。
例如,在以下代码中,Logger
类的两个静态成员都可以由 DBLogger
继承,然后再通过子类的名称使用这些静态成员,如 DBLogger.version
和 DBLogger.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
类,它拥有一个静态属性 maxThreadCount
。maxThreadCount
属性根据允许的平台而不同,因此这里定义了一个静态代码块,根据当前运行代码的平台是 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);