关于前端:JavaScript-Weekly-554ES2022-特性类静态初始化块

1次阅读

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

🥳 欢送有趣味的小伙伴,一起做点有意义的事!本文译者:天然卷

我发动了一个 周刊翻译打算,仓库地址,拜访地址

当初还很缺气味相投的小伙伴,纯属个人兴趣,当然对于晋升英语和前端技能也会有帮忙,要求:英语不要差的离谱、github 纯熟应用、有恒心、虚心、对本人做的事负责。

想参加的小伙伴,能够 wx 私信,也能够给仓库发 issue 留言,我博客也有具体的集体联系方式:daodaolee.cn

Ron Buckton 的 ECMAScript 提案“类动态初始化块”处于第 4 阶段,并打算蕴含在 ECMAScript2022 中。

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

  • 字段:创立(可选的初始化)实例属性。
  • 构造函数:实现设置前执行的代码块

为了设置类的动态局部,咱们只有动态字段。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 超类(具体请参阅库 enumify)

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'

这里须要收集动态字段,以便咱们能够遍历 enum 条目 (第 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: 在 v9.4.146 中未标记(源码)
  • SpiderMonkey: 标记在 v92 中,v93 不标记源码)
  • TypeScript:v4.4(源码)

5 JavaScript 是否变得越来越像 Java 或者变得很乱?

这是一个很小的性能并不会和其余性能有抵触,咱们曾经能够通过带有 static _ = ... 字段的工作区运行动态代码。动态块意味着这个工作区不再是必要的。
除此之外,类只是 JavaScript 程序员的泛滥工具之一。咱们能够应用也能够不应用,而且还有很多其余代替计划。

6 论断

类动态块是一个绝对简略的个性,它欠缺了类的动态个性。粗略地说,它是实例构造函数的动态版本。当咱们必须设置多个动态字段时,它是十分有用的。

相干链接

原文链接

翻译打算原文

正文完
 0