我想在类中实现常量,因为在代码中定位它们是有意义的。

到目前为止,我一直在用静态方法实现以下工作:

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

我知道有可能会摆弄原型,但许多人建议不要这样做。

在ES6类中有更好的实现常量的方法吗?


当前回答

您可以使用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);
  }
}

其他回答

给你!

const Status = Object.freeze(class Status {
  static Disabled = 0
  static Live = 1
})

加上其他答案,您需要导出类以在不同的类中使用。这是它的typescript版本。

/ / Constants.tsx const DEBUG: boolean = true; 导出类常量{ static get DEBUG(): boolean { 返回调试; } } / / Anotherclass.tsx import {Constants} from "Constants"; if (Constants.DEBUG) { console.log(“调试模式”) }

我发现的最干净的方法是使用TypeScript -参见如何实现类常量?

class MyClass {
    static readonly CONST1: string = "one";
    static readonly CONST2: string = "two";
    static readonly CONST3: string = "three";
}

就像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;
}

如果试图将const/variable作为类的静态对象;尝试使用散列(#)来定义占位符,而不是使用函数来访问它。

class Region {
    // initially empty, not accessible from outside
    static #empty_region = null; 

    /* 
        Make it visible to the outside and unchangeable 
        [note] created on first call to getter.
    */

    static EMPTY() {
        if (!this.#empty_region)
            this.#empty_region = new Region(0, 0, 0, 0);
        return this.#empty_region;
    }

    #reg = {x0:0, y0:0, x1:0, y1:0};

    constructor(x0, y0, x1, y1) { 
        this.setRegion(x0, y0, x1, y1);
    }

    // setters/getters
}

实现:

let someRegion = Region.EMPTY();

let anotherRegion = Region.EMPTY();