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?
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
Looking at a spec, 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:
- For each ClassElement m in order from methods
- If IsStatic of m is false, then
- Let status be the result of performing PropertyDefinitionEvaluation for m with arguments proto and false.
- Else,
- Let status be the result of performing PropertyDefinitionEvaluation for m with arguments F and false.
- If status is an abrupt completion, then
- Set the running execution context’s LexicalEnvironment to lex.
- 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.