Spec-Zone.ru › JavaScript

Статические блоки инициализации

Базовый Широко доступен

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна во всех браузерах с марта 2016 года.

Статические блоки инициализации объявляются внутри class. Они содержат инструкции, которые должны быть оценены во время инициализации класса. Это позволяет использовать более гибкую логику инициализации, чем static свойства, например, использовать try...catch или устанавливать несколько полей из одного значения. Инициализация выполняется в контексте текущего объявления класса, с доступом к закрытому состоянию, что позволяет классу обмениваться информацией о своих закрытых элементах с другими классами или функциями, объявленными в той же области видимости (аналогично классам "friend" в C++).

Попробуйте

class ClassWithStaticInitializationBlock {
  static staticProperty1 = "Property 1";
  static staticProperty2;
  static {
    this.staticProperty2 = "Property 2";
  }
}

console.log(ClassWithStaticInitializationBlock.staticProperty1);
// Expected output: "Property 1"
console.log(ClassWithStaticInitializationBlock.staticProperty2);
// Expected output: "Property 2"

Синтаксис

class ClassWithSIB {
  static {
    // …
  }
}

Описание

Без статических блоков инициализации сложная статическая инициализация может быть достигнута путем вызова статического метода после объявления класса:

class MyClass {
  static init() {
    // Access to private static fields is allowed here
  }
}

MyClass.init();

Однако этот подход раскрывает деталь реализации (метод init()) пользователю класса. С другой стороны, любая логика инициализации, объявленная вне класса, не имеет доступа к закрытым статическим полям. Статические блоки инициализации позволяют объявлять произвольную логику инициализации внутри класса и выполнять ее во время оценки класса.

class может иметь любое количество статических блоков инициализации static {} в теле своего класса. Они оцениваются вместе с любыми перемеженными инициализаторами статических полей в порядке их объявления. Любая статическая инициализация суперкласса выполняется первой, перед инициализацией его подклассов.

Область видимости переменных, объявленных внутри статического блока, локальна для этого блока. Это включает объявления var, function, const и let. Объявления var не будут подняты из статического блока.

var y = "Outer y";

class A {
  static field = "Inner y";
  static {
    // var y only hoisted inside block
    console.log(y); // undefined <-- not 'Outer y'

    var y = this.field;
  }
}

// var y defined in static block is not hoisted
// outside the block
console.log(y); // 'Outer y'

this внутри статического блока ссылается на объект конструктора класса. super.property может использоваться для доступа к статическим свойствам суперкласса. Однако следует отметить, что вызов super() в статическом блоке инициализации класса или использование объекта arguments является синтаксической ошибкой.

Инструкции оцениваются синхронно. Вы не можете использовать await или yield в этом блоке. (Считайте, что инструкции инициализации неявно обернуты в функцию.)

Область видимости статического блока вложена внутрь лексической области видимости тела класса и может получать доступ к закрытым именам, объявленным внутри класса, без вызова синтаксической ошибки.

Инициализаторы статических полей и статические блоки инициализации оцениваются один за другим. Блок инициализации может ссылаться на значения полей, находящихся над ним, но не под ним. Все статические методы добавляются заранее и доступны для вызова, хотя их вызов может вести себя не так, как ожидается, если они ссылаются на поля ниже текущего блока.

Примечание: Это более важно для закрытых статических полей, поскольку доступ к неинициализированному закрытому полю вызывает TypeError, даже если закрытое поле объявлено ниже. (Если закрытое поле не объявлено, это будет ранняя SyntaxError.)

Статический блок инициализации не может иметь декораторы (сам класс может).

Примеры

Несколько блоков

Код ниже демонстрирует класс со статическими блоками инициализации и перемеженными инициализаторами статических полей. Вывод показывает, что блоки и поля оцениваются в порядке выполнения.

class MyClass {
  static field1 = console.log("static field1");
  static {
    console.log("static block1");
  }
  static field2 = console.log("static field2");
  static {
    console.log("static block2");
  }
}
// 'static field1'
// 'static block1'
// 'static field2'
// 'static block2'

Обратите внимание, что любая статическая инициализация суперкласса выполняется первой, перед инициализацией его подклассов.

Использование this и super

this внутри статического блока ссылается на объект конструктора класса. Этот код показывает, как получить доступ к общедоступному статическому полю.

class A {
  static field = "static field";
  static {
    console.log(this.field);
  }
}
// 'static field'

Синтаксис super.property может использоваться внутри блока static для ссылки на статические свойства суперкласса.

class A {
  static field = "static field";
}

class B extends A {
  static {
    console.log(super.field);
  }
}
// 'static field'

Доступ к закрытым элементам

Пример ниже показывает, как может быть предоставлен доступ к закрытому полю экземпляра класса из объекта вне класса (пример из блога v8.dev):

let getDPrivateField;

class D {
  #privateField;
  constructor(v) {
    this.#privateField = v;
  }
  static {
    getDPrivateField = (d) => d.#privateField;
  }
}

console.log(getDPrivateField(new D("private"))); // 'private'

Спецификации

Спецификация
ECMAScript® 2027 Language Specification
# prod-ClassStaticBlock

Совместимость с браузерами

Настольные Мобильные Сервер
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
initialization_blocks
94
94
93
80
16.4
94
93
66
16.4
17.0
94
16.4
1.0.0
1.14
16.11.0

См. также

  • Руководство по использованию классов
  • Классы
  • static
  • class
  • Статические блоки инициализации классов на v8.dev (2021)
  • Функция ES2022: статические блоки инициализации классов от доктора Акселя Раушмайера (2021)

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Static_initialization_blocks

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API