我该如何在ES6类中创建一个"public static field"?

11 浏览
0 Comments

我该如何在ES6类中创建一个"public static field"?

我正在创建一个JavaScript类,并希望像Java中那样拥有公共静态字段。这是相关代码:

export default class Agent {
    CIRCLE: 1,
    SQUARE: 2,
    ...

这是我得到的错误:

line 2, col 11, Class properties must be methods. Expected '(' but instead saw ':'.

看起来ES6模块不允许这样做。有没有办法获得所需的行为,还是我必须编写一个getter?

admin 更改状态以发布 2023年5月23日
0
0 Comments

自从ECMAScript 2022之后,您可以像Java和C#等传统面向类的语言那样进行类似于以下的操作:

class MyClass {
    static myStaticProp = 42;
    myProp = 42;
    myProp2 = this.myProp;
    myBoundFunc = () => { console.log(this.myProp); };
    constructor() {
        console.log(MyClass.myStaticProp); // Prints '42'
        console.log(this.myProp); // Prints '42'
        this.myBoundFunc(); // Prints '42'
    }
}

以上等同于:

class MyClass {
    constructor() {
        this.myProp = 42;
        this.myProp2 = this.myProp;
        this.myBoundFunc = () => { console.log(this.myProp); };
        console.log(MyClass.myStaticProp); // Prints '42'
        console.log(this.myProp); // Prints '42'
        this.myBoundFunc(); // Prints '42'
    }
}
MyClass.myStaticProp = 42;

这些功能是由Daniel Ehrenberg等人在“静态类特性”和“类字段”提案中添加的。Google Chrome(和新Edge)从版本72开始支持这两个提案,相当于Node.js 12+。自Firefox 69以来,支持公共实例字段,自Firefox 75以来,支持静态实例字段。Safari从版本14.1开始同时支持这两个功能。更多信息请参见caniuse.com。

对于尚未支持这些功能的旧浏览器,您可以使用Babel将类字段转换为ES5。这需要启用@babel/plugin-proposal-class-properties插件(从v7.14.0开始默认在@babel/plugin-env中启用)。

与@kangax的解决方案声明getter相比,这个解决方案也可以更高效,因为这里直接访问属性,而不是通过调用函数访问。
编辑:一个统一的类字段提案现在已经进入第3阶段。
编辑(2020年2月):静态类功能已拆分为不同的提案。感谢@GOTO0!
编辑(2021年3月):除Safari外,所有在2020年4月之后发布的主要浏览器现在都支持此功能!
编辑(2021年6月):两个提案都已被ECMAScript语言委员会TC39接受,并且Safari在14.1版本中提供了此功能!

0
0 Comments

你可以使用accessor和"static"关键字制作"public static field":

class Agent {
    static get CIRCLE() {
      return 1;
    }
    static get SQUARE() {
      return 2;
    }
}
Agent.CIRCLE; // 1

查看规范,在14.5 — 类定义(Class Definitions)中,你会看到一些与此相关的内容:)

ClassElement[Yield] :
  MethodDefinition[?Yield]
  static MethodDefinition[?Yield] ;

因此,你可以跟随链接进入14.5.14 — 运行时语义:类定义求值(Runtime Semantics: ClassDefinitionEvaluation)以仔细检查它是否真的像看起来一样。特别是,在第20步:

  1. 对于从方法中按顺序排列的每个ClassElement m
    1. 如果m的IsStatic为false,则:
      1. 使用proto和false作为参数执行方法PropertyDefinitionEvaluation,令status为其结果。
    2. 否则,
      1. 使用F和false作为参数执行方法PropertyDefinitionEvaluation,令status为其结果
    3. 如果status是异常完成,则
      1. 将正在运行的执行上下文的词法环境设置为lex。
      2. 返回status。

IsStatic在14.5.9中定义

ClassElement : static MethodDefinition
返回true。

因此,使用"F"(构造函数,函数对象)作为参数调用PropertyMethodDefinition,它又在该对象上创建一个访问器方法

这个在至少IETP(技术预览版),以及6to5和Traceur编译器中已经可以使用了

0