Class static initialization block will be included in ES2022. Let's have a look first

Author: Dr. Axel Rauschmayer
Translator: front end Xiaozhi
Source: 2ality

There are dreams and dry goods. Wechat search [Daqian world] pays attention to this bowl washing wisdom who is still washing dishes in the early morning.
This article GitHub https://github.com/qq449245884/xiaozhi It has been included. There are complete test sites, materials and my series of articles for the interview of front-line large factories.

ECMAScript proposal by Ron Buckton Class static initialization block It has entered the fourth stage and is planned to be included in ECMAScript 2022.

To create an instance of a class, there are two structures in JavaScript:

  • Fields: create (optionally initialize) instance properties.
  • Constructor: a block of code that executes before setup completes.

For the setting of the static part of the class, we only have static fields. ECMAScript recommends the introduction of static initialization blocks for classes. In general, it works on static classes like constructors on instances.

1. Why do we need static blocks in classes?

External functions often work well when setting static fields:

class Translator {
  static translations = {
    yes: 'ja',
    no: 'nein',
    maybe: 'vielleicht',
  };
  static englishWords = extractEnglish(this.translations);
  static germanWords = extractGerman(this.translations);
}
function extractEnglish(translations) {
  return Object.keys(translations);
}
function extractGerman(translations) {
  return Object.values(translations);
}

Using the external functions extractEnglish() and extractGerman() works well in this case because we can see that they are called from within the class and are completely independent of the class.

If we want to set two static fields at the same time, things become less elegant.

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);
  }
}

This time, there are several questions.

  • Calling initializeTranslator() is an additional step, either outside the class after the class is created. Or by A workaround (line A).
  • initializeTranslator() cannot access the private data of the Translator.

Through the proposed static block (line A), we have A more elegant solution.

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);
    }
  }
}

2. A more complex example

One way to implement enumeration in JavaScript is through the superclass Enum with accessibility

class Enum {
  static collectStaticFields() {
    // Static methods are not enumerable and thus ignored
    this.enumKeys = Object.keys(this);
  }
}
class ColorEnum extends Enum {
  static red = Symbol('red');
  static green = Symbol('green');
  static blue = Symbol('blue');
  static _ = this.collectStaticFields(); // (A)

  static logColors() {
    for (const enumKey of this.enumKeys) { // (B)
      console.log(enumKey);
    }
  }
}
ColorEnum.logColors();

// Output:
// 'red'
// 'green'
// 'blue'

We need to collect static fields so that we can traverse the keys of enumerated items (line B). This is the last step after creating all static fields. We use A workaround again (line A), and the static block will be more elegant.

3. Details

The specific contents of static blocks are relatively logical (in contrast, the rules of instance members are more complex):

  • Each class can have more than one static block.
  • The execution of static blocks is interleaved with the execution of static field initializers.
  • Static members of a superclass are executed before static members of subclasses.

The following code shows these rules:

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'

4. Support class static blocks in the engine

  • V8: unflagged in v9.4.146 (source)
  • SpiderMonkey: behind a flag in v92, intent to ship unflagged in v93 (source)
  • TypeScript: v4.4 (source)

5. Has JS become too Java like and / or a mess?

This is a small feature and will not compete with other features. We can already use static = To run static code. Static blocks mean that this workaround is no longer needed.

In addition, classes are just one of many tools on the belt of JavaScript programmers. Some of us use it, others don't, and there are many alternatives. Even JS code that uses classes often uses functions and is often lightweight.

6. Summary

Class static block is a relatively simple function, which improves the static function of class. Roughly speaking, it is a static version of the instance constructor. It is mainly useful when we need to set more than one static field.

~After that, I'm the person who wants to go home and set up a stall after retirement. I'll see you next time!

The bugs that may exist after code deployment cannot be known in real time. Afterwards, in order to solve these bugs, we spent a lot of time on log debugging. By the way, we recommend a useful BUG monitoring tool Fundebug.

Original text: https://2ality.com/2021/09/cl...

communication

There are dreams and dry goods. Wechat search [Daqian world] pays attention to this bowl washing wisdom who is still washing dishes in the early morning.

This article GitHub https://github.com/qq44924588... It has been included. There are complete test sites, materials and my series of articles for the interview of front-line large factories.

Tags: Front-end Vue.js

Posted on Tue, 23 Nov 2021 22:51:26 -0500 by essjay_d12