The class-static-block proposal, which entered Stage4 in 2021.9.1, is a proposal based on class enhancements.

This week we’ll discuss this feature in conjunction with ES2022 feature: Class Static Initialization Blocks.

An overview of the

Why do we need class static block? One reason is the need for flexible assignment of Class static variables. For example, if we want to batch initialize a static variable within a Class, we have to write a useless _ variable to do the initialization logic:

class Translator {
  static translations = {
    yes: 'ja'.no: 'nein'.maybe: 'vielleicht'};static englishWords = [];
  static germanWords = [];
  static _ = initializeTranslator( // (A)
    this.translations, this.englishWords, this.germanWords);
}
function initializeTranslator(translations, englishWords, germanWords) {
  for (const [english, german] of Object.entries(translations)) { englishWords.push(english); germanWords.push(german); }}Copy the code

And why do we put initializeTranslator outside? Because you can’t write code blocks inside a Class, a serious problem is that external functions can’t access attributes inside the Class, so you have to do a lot of boring passing.

From this example, we need to make two compromises in order to customize the static variable initialization logic:

  1. Defines a function externally that takes a large number of Class member variables.
  2. Define a meaningless variable inside the Class_Used to start the function logic.

This is too much code to pursue. Wouldn’t it be simpler to do this logic inside the Class? This is the class static block feature:

class Translator {
  static translations = {
    yes: 'ja'.no: 'nein'.maybe: 'vielleicht'};static englishWords = [];
  static germanWords = [];
  static { // (A)
    for (const [english, german] of Object.entries(this.translations)) {
      this.englishWords.push(english);
      this.germanWords.push(german); }}}Copy the code

The static keyword is not followed by a variable, but by a code block. Inside this code block, you can access all member variables of the class, including the # private variable.

The article concludes with an introduction to this feature and a final detail, which is the order of execution. That is, all static variables or blocks are executed in order, with the parent class taking precedence:

class SuperClass {
  static superField1 = console.log('superField1');
  static {
    assert.equal(this, SuperClass);
    console.log('static block 1 SuperClass');
  }
  static superField2 = console.log('superField2');
  static {
    console.log('static block 2 SuperClass'); }}class SubClass extends SuperClass {
  static subField1 = console.log('subField1');
  static {
    assert.equal(this, SubClass);
    console.log('static block 1 SubClass');
  }
  static subField2 = console.log('subField2');
  static {
    console.log('static block 2 SubClass'); }}// Output:
// 'superField1'
// 'static block 1 SuperClass'
// 'superField2'
// 'static block 2 SuperClass'
// 'subField1'
// 'static block 1 SubClass'
// 'subField2'
// 'static block 2 SubClass'
Copy the code

A Class can have more than one Class static block, either a parent or a subclass, in different order of execution. This option is left to the user because the order of execution is the same as the order of writing.

Intensive reading

Combined with the proposal, the class Static Block also has the motivation of giving a mechanism to access private variables:

let getX;

export class C {
  #x
  constructor(x) {
    this.#x = { data: x };
  }

  static {
    // getX has privileged access to #x
    getX = (obj) = >obj.#x; }}export function readXData(obj) {
  return getX(obj).data;
}
Copy the code

The Class static block can access both private and global variables. The Class static block can access both private and global variables. The Class static block can access both private and global variables. So you can use it to do a “liyingwaihe”.

I don’t think this is a good idea, but rather a “BUG”, because any break in the rules creates a problem for maintainability, unless the feature is used in a stable tool/framework layer to do some convenience work and ultimately improve the experience of application coding, which is acceptable.

Finally, realize that class static Block does not add any new functionality per se. We could have simply replaced it with normal static variables, but it just doesn’t feel natural to write, so this feature can be interpreted as a complement to a bug, or a syntactic improvement.

conclusion

In general, a class static block creates a block scope within the class that has access to private variables within the class. This block scope is initialized only once when the engine calls it, which is a convenient syntax.

There are some objections that this is complicating JS and that JS is becoming more and more Like Java, but I agree with the author that Class is not everything in JS and that more and more code is now using functional syntax. Even in scenarios where Class is used, there are a lot of function declarations, so the Class Static Block proposal is not really that sensitive to the developer.

Class Static Block · Issue #351 · dT-fe /weekly

If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays. Front end Intensive Reading – Helps you filter the right content.

Pay attention to the front end of intensive reading wechat public account

Copyright Notice: Freely reproduced – Non-commercial – Non-derivative – Remain signed (Creative Commons 3.0 License)