static

Baseline 已廣泛支援

此特性已經非常成熟,並且適用於許多裝置和瀏覽器版本。自 2016 年 3 月以來,它已在所有瀏覽器中可用。

static 關鍵字定義了一個類的靜態方法或欄位,或者一個靜態初始化塊(有關此用法的更多資訊,請參閱連結)。靜態屬性不能直接透過類的例項訪問。相反,它們是在類本身上訪問的。

靜態方法通常是實用工具函式,例如建立或克隆物件的函式,而靜態屬性對於快取、固定配置或任何其他不需要在例項之間複製的資料非常有用。

注意: 在類的上下文中,MDN Web Docs 內容將術語屬性和欄位互換使用。

試一試

class ClassWithStaticMethod {
  static staticProperty = "someValue";
  static staticMethod() {
    return "static method has been called.";
  }
  static {
    console.log("Class static initialization block called");
  }
}

console.log(ClassWithStaticMethod.staticProperty);
// Expected output: "someValue"
console.log(ClassWithStaticMethod.staticMethod());
// Expected output: "static method has been called."

語法

js
class ClassWithStatic {
  static staticField;
  static staticFieldWithInitializer = value;
  static staticMethod() {
    // …
  }
}

還有一些額外的語法限制

  • 靜態屬性(欄位或方法)的名稱不能是 prototype
  • 類欄位(靜態或例項)的名稱不能是 constructor

描述

本頁介紹類的公共靜態屬性,包括靜態方法、靜態訪問器和靜態欄位。

公共靜態特性使用 static 關鍵字宣告。它們在類評估時使用 [[DefineOwnProperty]] 語義(本質上是 Object.defineProperty())新增到類建構函式中。它們再次從類建構函式中訪問。

靜態方法通常是實用工具函式,例如建立或克隆例項的函式。公共靜態欄位在您希望每個類只存在一次欄位,而不是在您建立的每個類例項上都存在時非常有用。這對於快取、固定配置或任何其他不需要在例項之間複製的資料非常有用。

靜態欄位名稱可以是計算得出的。計算表示式中的 this 值是圍繞類定義的 this,並且引用類的名稱會導致 ReferenceError,因為類尚未初始化。awaityield 在此表示式中按預期工作。

靜態欄位可以有初始化器。沒有初始化器的靜態欄位被初始化為 undefined。公共靜態欄位不會在子類上重新初始化,但可以透過原型鏈訪問。

js
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 指的是基類建構函式。

js
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"

表示式是同步評估的。您不能在初始化器表示式中使用 awaityield。(可以將初始化器表示式看作是隱式包裝在一個函式中。)

靜態欄位初始化器和靜態初始化塊是逐個評估的。欄位初始化器可以引用其上方欄位的值,但不能引用其下方欄位的值。所有靜態方法都預先新增,並且可以訪問,儘管如果它們引用了正在初始化的欄位下方的欄位,則呼叫它們可能不會按預期行為。

注意: 這對於私有靜態欄位更為重要,因為訪問未初始化的私有欄位會丟擲 TypeError,即使私有欄位是在下方宣告的。(如果私有欄位未宣告,則會是早期的 SyntaxError。)

示例

在類中使用靜態成員

以下示例演示了幾件事

  1. 如何在類上定義靜態成員(方法或屬性)。
  2. 具有靜態成員的類可以被子類化。
  3. 靜態成員可以和不能如何呼叫。
js
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 關鍵字。

js
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

js
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® 2026 語言規範
# sec-class-definitions

瀏覽器相容性

另見