static
static
关键字为类定义静态方法或字段,或静态初始化块(有关此用法的更多信息,请参阅链接)。静态属性无法在类的实例上直接访问。相反,它们是在类本身上访问的。
静态方法通常是实用程序函数,例如创建或克隆对象的函数,而静态属性则用于缓存、固定配置或任何其他不需要在实例之间复制的数据。
注意:在类的上下文中,MDN 网页文档内容交替使用属性和字段这两个术语。
试一试
语法
class ClassWithStatic {
static staticField;
static staticFieldWithInitializer = value;
static staticMethod() {
// …
}
}
还有一些额外的语法限制
- 静态属性(字段或方法)的名称不能为
prototype
。 - 类字段(静态或实例)的名称不能为
constructor
。
描述
此页面介绍了类的公共静态属性,其中包括静态方法、静态访问器和静态字段。
公共静态功能使用static
关键字声明。它们在类评估时使用[[DefineOwnProperty]]
语义添加到类构造函数中(这本质上是Object.defineProperty()
)。它们再次从类构造函数中访问。
静态方法通常是实用程序函数,例如创建或克隆实例的函数。当您希望字段仅在每个类中存在一次,而不是在您创建的每个类实例上存在一次时,公共静态字段很有用。这对于缓存、固定配置或任何其他不需要在实例之间复制的数据很有用。
静态字段名称可以是计算的。计算表达式中的this
值是围绕类定义的this
,并且引用类的名称是ReferenceError
,因为类尚未初始化。await
和yield
在此表达式中按预期工作。
静态字段可以有初始化程序。没有初始化程序的静态字段初始化为undefined
。公共静态字段在子类中不会重新初始化,但可以通过原型链访问。
class ClassWithStaticField {
static staticField;
static staticFieldWithInitializer = "static field";
}
class SubclassWithStaticField extends ClassWithStaticField {
static subStaticField = "subclass field";
}
console.log(Object.hasOwn(ClassWithStaticField, "staticField")); // true
console.log(ClassWithStaticField.staticField); // undefined
console.log(ClassWithStaticField.staticFieldWithInitializer); // "static field"
console.log(SubclassWithStaticField.staticFieldWithInitializer); // "static field"
console.log(SubclassWithStaticField.subStaticField); // "subclass field"
在字段初始化程序中,this
指的是当前类(您也可以通过其名称访问它),而super
指的是基类构造函数。
class ClassWithStaticField {
static baseStaticField = "base static field";
static anotherBaseStaticField = this.baseStaticField;
static baseStaticMethod() {
return "base static method output";
}
}
class SubClassWithStaticField extends ClassWithStaticField {
static subStaticField = super.baseStaticMethod();
}
console.log(ClassWithStaticField.anotherBaseStaticField); // "base static field"
console.log(SubClassWithStaticField.subStaticField); // "base static method output"
表达式同步计算。您不能在初始化程序表达式中使用await
或yield
。(可以将初始化程序表达式视为隐式地包装在一个函数中。)
静态字段初始化程序和静态初始化块逐个计算。字段初始化程序可以引用其上方的字段值,但不能引用其下方的字段值。所有静态方法都会预先添加,并且可以访问,尽管如果它们引用正在初始化的字段下方的字段,则调用它们的行为可能与预期不符。
注意:对于私有静态字段,这一点更为重要,因为访问未初始化的私有字段会抛出TypeError
,即使私有字段声明在下方。(如果未声明私有字段,则会是早期的SyntaxError
。)
示例
在类中使用静态成员
以下示例演示了几件事
- 如何在类上定义静态成员(方法或属性)。
- 具有静态成员的类可以被子类化。
- 如何以及如何不能调用静态成员。
class Triple {
static customName = "Tripler";
static description = "I triple any number you provide";
static calculate(n = 1) {
return n * 3;
}
}
class SquaredTriple extends Triple {
static longDescription;
static description = "I square the triple of any number you provide";
static calculate(n) {
return super.calculate(n) * super.calculate(n);
}
}
console.log(Triple.description); // 'I triple any number you provide'
console.log(Triple.calculate()); // 3
console.log(Triple.calculate(6)); // 18
const tp = new Triple();
console.log(SquaredTriple.calculate(3)); // 81 (not affected by parent's instantiation)
console.log(SquaredTriple.description); // 'I square the triple of any number you provide'
console.log(SquaredTriple.longDescription); // undefined
console.log(SquaredTriple.customName); // 'Tripler'
// This throws because calculate() is a static member, not an instance member.
console.log(tp.calculate()); // 'tp.calculate is not a function'
从另一个静态方法调用静态成员
为了在同一类的另一个静态方法中调用静态方法或属性,您可以使用this
关键字。
class StaticMethodCall {
static staticProperty = "static property";
static staticMethod() {
return `Static method and ${this.staticProperty} has been called`;
}
static anotherStaticMethod() {
return `${this.staticMethod()} from another static method`;
}
}
StaticMethodCall.staticMethod();
// 'Static method and static property has been called'
StaticMethodCall.anotherStaticMethod();
// 'Static method and static property has been called from another static method'
从类构造函数和其他方法调用静态成员
静态成员不能从非静态方法中使用this
关键字直接访问。您需要使用类名调用它们:CLASSNAME.STATIC_METHOD_NAME()
/ CLASSNAME.STATIC_PROPERTY_NAME
或将方法作为constructor
的属性调用:this.constructor.STATIC_METHOD_NAME()
/ this.constructor.STATIC_PROPERTY_NAME
class StaticMethodCall {
constructor() {
console.log(StaticMethodCall.staticProperty); // 'static property'
console.log(this.constructor.staticProperty); // 'static property'
console.log(StaticMethodCall.staticMethod()); // 'static method has been called.'
console.log(this.constructor.staticMethod()); // 'static method has been called.'
}
static staticProperty = "static property";
static staticMethod() {
return "static method has been called.";
}
}
规范
规范 |
---|
ECMAScript 语言规范 # sec-class-definitions |
浏览器兼容性
BCD 表格仅在浏览器中加载