acbabis acbabis - 4 months ago 14
Javascript Question

How do I make a "public static field" in an ES6 class?

I'm making a Javascript class and I'd like to have a public static field like in Java. This is the relevant code:

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


This is the error I get:

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


It looks like ES6 modules don't allow this. Is there a way to get the desired behavior or do I have to write a getter?

Answer

You make "public static field" using accessor and a "static" keyword:

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

Agent.CIRCLE; // 1

It's always good to take a look at a spec and see if there's anything resembling what you need.

Looking at 14.5 — Class Definitions — you'd see something suspiciously relevant :)

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

So from there you can follow to 14.5.14 — Runtime Semantics: ClassDefinitionEvaluation — to double check if it really does what it looks like it does. Specifically, step 20:

  1. For each ClassElement m in order from methods
    1. If IsStatic of m is false, then
      1. Let status be the result of performing PropertyDefinitionEvaluation for m with arguments proto and false.
    2. Else,
      1. Let status be the result of performing PropertyDefinitionEvaluation for m with arguments F and false.
    3. If status is an abrupt completion, then
      1. Set the running execution context’s LexicalEnvironment to lex.
      2. Return status.

IsStatic is defined earlier in 14.5.9

ClassElement : static MethodDefinition
Return true.

So PropertyMethodDefinition is called with "F" (constructor, function object) as an argument, which in its turn creates an accessor method on that object.

This already works in at least IETP (tech preview), as well as 6to5 and Traceur compilers.

Comments