Coder Perfect

In ES6 classes, how do you declare static constants?

Problem

I want to implement constants in a class, because that’s where it makes sense to locate them in the code.

So far, I’ve been using static methods to implement the following workaround:

class MyClass {
    static constant1() { return 33; }
    static constant2() { return 2; }
    // ...
}

I understand that tinkering with prototypes is possible, but many people advise against it.

Is there a more efficient way to use constants in ES6 classes?

Asked by Jérôme Verstrynge

Solution #1

Here are a few ideas for you:

The module allows you to export a const. Depending on your situation, you might simply:

export const constant1 = 33;

And, if necessary, import it from the module. Alternatively, you might declare a static get accessor based on your static method idea:

const constant1 = 33,
      constant2 = 2;
class Example {

  static get constant1() {
    return constant1;
  }

  static get constant2() {
    return constant2;
  }
}

You won’t need parentheses this way:

const one = Example.constant1;

Babel REPL Example

Then, as you say, since a class is just syntactic sugar for a function you can just add a non-writable property like so:

class Example {
}
Object.defineProperty(Example, 'constant1', {
    value: 33,
    writable : false,
    enumerable : true,
    configurable : false
});
Example.constant1; // 33
Example.constant1 = 15; // TypeError

It would be ideal if we could simply do the following:

class Example {
    static const constant1 = 33;
}

Unfortunately, this class property syntax is just in an ES7 proposal, and even then, adding const to the property will be impossible.

Answered by CodingIntrigue

Solution #2

class Whatever {
    static get MyConst() { return 10; }
}

let a = Whatever.MyConst;

It appears to work for me.

Answered by Benny Jobigan

Solution #3

I’m using babel, and the syntax below works for me:

class MyClass {
    static constant1 = 33;
    static constant2 = {
       case1: 1,
       case2: 2,
    };
    // ...
}

MyClass.constant1 === 33
MyClass.constant2.case1 === 1

Please keep in mind that the setting “stage-0” is required. To set it up, follow these steps:

npm install --save-dev babel-preset-stage-0

// in .babelrc
{
    "presets": ["stage-0"]
}

Update:

currently use stage-3

Answered by borracciaBlu

Solution #4

The following is taken from the document:

This means that it is intentionally like this.

Is it possible to declare a variable in the constructor?

constructor(){
    this.key = value
}

Answered by DevAlien

Solution #5

You may also use Object.freeze to make your class(es6)/constructor function(es5) object immutable:

class MyConstants {}
MyConstants.staticValue = 3;
MyConstants.staticMethod = function() {
  return 4;
}
Object.freeze(MyConstants);
// after the freeze, any attempts of altering the MyConstants class will have no result
// (either trying to alter, add or delete a property)
MyConstants.staticValue === 3; // true
MyConstants.staticValue = 55; // will have no effect
MyConstants.staticValue === 3; // true

MyConstants.otherStaticValue = "other" // will have no effect
MyConstants.otherStaticValue === undefined // true

delete MyConstants.staticMethod // false
typeof(MyConstants.staticMethod) === "function" // true

Attempting to change the class will result in a soft-fail (it will not throw any errors, but it will have no effect).

Answered by rodrigo.botti

Post is based on https://stackoverflow.com/questions/32647215/declaring-static-constants-in-es6-classes