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

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

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

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

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


当前回答

如果试图将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();

其他回答

您可以使用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
})
class Whatever {
    static get MyConst() { return 10; }
}

let a = Whatever.MyConst;

似乎对我有用。

通过冻结类,可以使“常量”为只读(不可变)。如。

class Foo {
    static BAR = "bat"; //public static read-only
}

Object.freeze(Foo); 

/*
Uncaught TypeError: Cannot assign to read only property 'BAR' of function 'class Foo {
    static BAR = "bat"; //public static read-only
}'
*/
Foo.BAR = "wut";

也许把你所有的常量都放在一个冻结的对象里?

class MyClass {

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

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

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