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