it-swarm.com.de

Statische Konstanten in ES6-Klassen deklarieren?

Ich möchte Konstanten in einem class implementieren, da es dort sinnvoll ist, sie im Code zu lokalisieren.

Bisher habe ich die folgende Problemumgehung mit statischen Methoden implementiert:

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

Ich weiß, dass es die Möglichkeit gibt, mit Prototypen herumzuspielen, aber viele raten davon ab.

Gibt es eine bessere Möglichkeit, Konstanten in ES6-Klassen zu implementieren?

263

Hier sind ein paar Dinge, die Sie tun könnten:

Exportieren Sie ein const aus dem Modul . Abhängig von Ihrem Anwendungsfall können Sie einfach:

export const constant1 = 33;

Und importieren Sie das ggf. aus dem Modul. Oder, aufbauend auf Ihrer Idee einer statischen Methode, könnten Sie staticget accessor deklarieren:

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

  static get constant1() {
    return constant1;
  }

  static get constant2() {
    return constant2;
  }
}

Auf diese Weise brauchen Sie keine Klammern:

const one = Example.constant1;

Babel REPL Beispiel

Dann können Sie, wie Sie sagen, da ein class nur syntaktischer Zucker für eine Funktion ist, einfach eine nicht beschreibbare Eigenschaft wie folgt hinzufügen:

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

Es könnte schön sein, wenn wir einfach so etwas machen könnten:

class Example {
    static const constant1 = 33;
}

Aber leider ist dieses Klasseneigenschaftensyntax nur in einem ES7-Vorschlag enthalten, und selbst dann kann der Eigenschaft kein const hinzugefügt werden.

328
CodingIntrigue

Ich verwende babel und die folgende Syntax funktioniert für mich:

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

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

Bitte beachten Sie, dass Sie das Preset "stage-0" benötigen.
So installieren Sie es:

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

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

pdate:

benutze momentan stage-3

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

let a = Whatever.MyConst;

Scheint für mich zu arbeiten.

19
Benny Jobigan

In dieses Dokument heißt es:

Es gibt (absichtlich) keine direkte deklarative Methode zum Definieren von Klasseneigenschaften für Prototypdaten (außer Methoden) oder Instanzeigenschaften

Das bedeutet, dass es absichtlich so ist.

Vielleicht können Sie im Konstruktor eine Variable definieren?

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

Es ist auch möglich, Object.freeze für Ihr Klassenobjekt (es6)/Konstruktorfunktion (es5) zu verwenden, um es unveränderlich zu machen:

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

Der Versuch, die Klasse zu ändern, führt zu einem Soft-Fail (wirft keine Fehler, es hat einfach keine Auswirkung).

10
rodrigo.botti

Vielleicht legen Sie einfach alle Ihre Konstanten in ein gefrorenes Objekt?

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

Wie https://stackoverflow.com/users/2784136/rodrigo-botti sagte, ich denke, Sie suchen nach Object.freeze(). Hier ist ein Beispiel für eine Klasse mit unveränderlicher Statik:

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

Hier ist eine weitere Möglichkeit, die Sie tun können

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

Hinweis - Die Reihenfolge ist wichtig, Sie können die obigen Konstanten nicht haben

Verwendung console.log (Auto.CONSTANT1);

1
user3871424

Sie können eine Möglichkeit zum Definieren statischer Konstanten für eine Klasse mithilfe einer ungeraden Funktion von ES6-Klassen erstellen. Da Statiken von ihren Unterklassen geerbt werden, können Sie Folgendes tun:

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