关于前端:类静态初始化块即将纳入ES2022我们先一睹为快

7次阅读

共计 3486 个字符,预计需要花费 9 分钟才能阅读完成。

作者:Dr. Axel Rauschmayer
译者:前端小智
起源:2ality

有幻想,有干货,微信搜寻【大迁世界】关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

Ron Buckton 提出的 ECMAScript 提案 “ 类动态初始化块 ” 已进入第四阶段,打算纳入 ECMAScript 2022。

为了建设一个类的实例, 在 JavaScript 中有两个构造:

  • 字段:创立 (可抉择初始化) 实例属性。
  • 构造函数: 在 setup 实现之前执行的代码块。

对于类的动态局部的设置,咱们只有动态字段。ECMAScript 倡议为类引入动态初始化块,大抵上,它对动态类的作用就像构造函数对实例的作用。

1. 为什么咱们须要类中的动态块?

在设置动态字段时,应用内部函数通常也能够很好地工作:

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

应用内部函数 extractEnglish()extractGerman() 在这种状况下成果很好,因为咱们能够看到它们是从类外部调用的,而且它们齐全独立于类。

如果咱们想同时设置两个动态字段,事件就变得不那么优雅。

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

这一次,有几个问题。

  • 调用 initializeTranslator() 是一个额定的步骤,要么在创立类之后,在类之外执行。或者通过一个变通方法来执行( A 行)。
  • initializeTranslator() 不能拜访 Translator 的公有数据。

通过提出的动态块(A 行),咱们有更优雅的解决方案。

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. 一个更简单的例子

在 JavaScript 中实现枚举的一种办法是通过带有辅助性能的超类Enum

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'

咱们须要收集动态字段,以便咱们能够遍历枚举项的键( B 行)。这是在创立所有动态字段之后的最初一步。咱们再次应用一个变通方法( A 行),动态块会更优雅。

3. 详情

动态块的具体内容相对来说是合乎逻辑的(相比之下,实例成员的规定更为简单):

  • 每个类能够有一个以上的动态块。
  • 动态块的执行是与动态字段初始化器的执行交织进行的。
  • 超类的动态成员在子类的动态成员之前被执行。

上面的代码展现了这些规定:

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. 在引擎中反对类动态块

  • 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.JS 是否变得太像 Java 和 / 或一塌糊涂?

这是一个很小的性能,不会与其余性能竞争。咱们曾经能够通过 static _ = ... 的字段来运行动态代码。动态块意味着这种变通方法不再须要了。

除此之外,类只是 JavaScript 程序员腰带上的泛滥工具之一。咱们中的一些人应用它,另一些人不应用它,而且有许多代替计划。即便是应用类的 JS 代码,也常常应用函数,而且往往是轻量级的。

6. 总结

类动态块是一个绝对简略的性能,它欠缺了类的动态性能。粗略来说,它是实例构造函数的动态版本。它次要在咱们须要设置一个以上的动态字段时有用。

~ 完,我是刷碗智,励志等退休后,要回家摆地摊的人,咱们下期见!


代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。

原文:https://2ality.com/2021/09/cl…

交换

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq44924588… 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

正文完
 0