私はclass
で定数を実装したいのですが、それはコードの中でそれらを見つけるのが理にかなっているところです。
これまでは、静的メソッドを使用して次の回避策を実装していました。
class MyClass {
static constant1() { return 33; }
static constant2() { return 2; }
// ...
}
私はプロトタイプをいじるの可能性があることを知っていますが、多くの人はこれに反対します。
ES6クラスに定数を実装するためのより良い方法はありますか?
これがあなたがすることができるいくつかのことです:
モジュール からconst
をエクスポートします。あなたのユースケースに応じて、あなただけのことができます:
export const constant1 = 33;
そして必要ならモジュールからそれをインポートしてください。あるいは、静的メソッドのアイデアに基づいて、static
get accessor :を宣言することもできます。
const constant1 = 33,
constant2 = 2;
class Example {
static get constant1() {
return constant1;
}
static get constant2() {
return constant2;
}
}
そうすれば、括弧は必要ありません。
const one = Example.constant1;
それから、あなたが言うように、class
は関数の単なる構文上の糖であるので、あなたはそのように書き込み不可能なプロパティを追加することができます:
class Example {
}
Object.defineProperty(Example, 'constant1', {
value: 33,
writable : false,
enumerable : true,
configurable : false
});
Example.constant1; // 33
Example.constant1 = 15; // TypeError
以下のようなことができればいいかもしれません。
class Example {
static const constant1 = 33;
}
しかし残念ながら、この クラスプロパティの構文 はES7での提案にしか含まれておらず、それでもconst
をプロパティに追加することはできません。
私はbabel
を使用していて、次の構文がうまくいきました。
class MyClass {
static constant1 = 33;
static constant2 = {
case1: 1,
case2: 2,
};
// ...
}
MyClass.constant1 === 33
MyClass.constant2.case1 === 1
プリセット"stage-0"
が必要だと考えてください。
インストールするには:
npm install --save-dev babel-preset-stage-0
// in .babelrc
{
"presets": ["stage-0"]
}
更新:
現在stage-2
を使用しています
class Whatever {
static get MyConst() { return 10; }
}
let a = Whatever.MyConst;
私のために働くようだ。
この文書 でそれは述べている:
プロトタイプデータプロパティ(メソッド以外)クラスプロパティ、またはインスタンスプロパティを定義する直接的な宣言的な方法は(意図的に)ありません。
これは意図的にこのようになっていることを意味します。
たぶんあなたはコンストラクタで変数を定義することができますか?
constructor(){
this.key = value
}
クラス(es6)/コンストラクタ関数(es5)オブジェクトにObject.freeze
を使用して不変にすることもできます。
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
クラスを変更しようとすると、ソフトフェイルが発生します(エラーは発生しません。単に効果はありません)。
凍結したオブジェクトにすべての定数を入れるだけでいいのでしょうか。
class MyClass {
constructor() {
this.constants = Object.freeze({
constant1: 33,
constant2: 2,
});
}
static get constant1() {
return this.constants.constant1;
}
doThisAndThat() {
//...
let value = this.constants.constant2;
//...
}
}
https://stackoverflow.com/users/2784136/rodrigo-botti のように/ Object.freeze()
を探していると思います。これは不変の統計を持つクラスの例です。
class User {
constructor(username, age) {
if (age < User.minimumAge) {
throw new Error('You are too young to be here!');
}
this.username = username;
this.age = age;
this.state = 'active';
}
}
User.minimumAge = 16;
User.validStates = ['active', 'inactive', 'archived'];
deepFreeze(User);
function deepFreeze(value) {
if (typeof value === 'object' && value !== null) {
Object.freeze(value);
Object.getOwnPropertyNames(value).forEach(property => {
deepFreeze(value[property]);
});
}
return value;
}
ES6クラスの奇妙な機能を使用して、クラスに静的定数を定義する方法を作成できます。静的はサブクラスによって継承されるので、次のことができます。
const withConsts = (map, BaseClass = Object) => {
class ConstClass extends BaseClass { }
Object.keys(map).forEach(key => {
Object.defineProperty(ConstClass, key, {
value: map[key],
writable : false,
enumerable : true,
configurable : false
});
});
return ConstClass;
};
class MyClass extends withConsts({ MY_CONST: 'this is defined' }) {
foo() {
console.log(MyClass.MY_CONST);
}
}
これがあなたができるもう一つの方法です。
/*
one more way of declaring constants in a class,
Note - the constants have to be declared after the class is defined
*/
class Auto{
//other methods
}
Auto.CONSTANT1 = "const1";
Auto.CONSTANT2 = "const2";
console.log(Auto.CONSTANT1)
console.log(Auto.CONSTANT2);
注 - 順序は重要です。上記の定数は使用できません
使用法console.log(Auto.CONSTANT1);