web-dev-qa-db-ja.com

ES6クラスで静的定数を宣言する

私はclassで定数を実装したいのですが、それはコードの中でそれらを見つけるのが理にかなっているところです。

これまでは、静的メソッドを使用して次の回避策を実装していました。

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

私はプロトタイプをいじるの可能性があることを知っていますが、多くの人はこれに反対します。

ES6クラスに定数を実装するためのより良い方法はありますか?

247

これがあなたがすることができるいくつかのことです:

モジュール からconstをエクスポートします。あなたのユースケースに応じて、あなただけのことができます:

export const constant1 = 33;

そして必要ならモジュールからそれをインポートしてください。あるいは、静的メソッドのアイデアに基づいて、staticget accessor :を宣言することもできます。

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

  static get constant1() {
    return constant1;
  }

  static get constant2() {
    return constant2;
  }
}

そうすれば、括弧は必要ありません。

const one = Example.constant1;

Babel REPL例

それから、あなたが言うように、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をプロパティに追加することはできません。

307
CodingIntrigue

私は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を使用しています

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

let a = Whatever.MyConst;

私のために働くようだ。

17
Benny Jobigan

この文書 でそれは述べている:

プロトタイプデータプロパティ(メソッド以外)クラスプロパティ、またはインスタンスプロパティを定義する直接的な宣言的な方法は(意図的に)ありません。

これは意図的にこのようになっていることを意味します。

たぶんあなたはコンストラクタで変数を定義することができますか?

constructor(){
    this.key = value
}
13
DevAlien

クラス(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

クラスを変更しようとすると、ソフトフェイルが発生します(エラーは発生しません。単に効果はありません)。

10
rodrigo.botti

凍結したオブジェクトにすべての定数を入れるだけでいいのでしょうか。

class MyClass {

    constructor() {
        this.constants = Object.freeze({
            constant1: 33,
            constant2: 2,
        });
    }

    static get constant1() {
        return this.constants.constant1;
    }

    doThisAndThat() {
        //...
        let value = this.constants.constant2;
        //...
    }
}
5
aRIEL

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;
}
4
jeffwtribble

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);
  }
}
1
TbWill4321

これがあなたができるもう一つの方法です。

/*
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);

0
user3871424