在ES6类中声明静态常量?

2020/10/03 08:01 · javascript ·  · 0评论

我想在中实现常量class,因为在代码中找到常量是很有意义的。

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

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

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

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

您可以执行以下操作:

const模块中导出a 根据您的用例,您可以:

export const constant1 = 33;

并在必要时从模块导入该文件。或者,基于您的静态方法思想,您可以声明一个static get访问器

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

  static get constant1() {
    return constant1;
  }

  static get constant2() {
    return constant2;
  }
}

这样,您将不需要括号:

const one = Example.constant1;

Babel REPL示例

然后,就像您说的那样,由于aclass只是函数的语法糖,因此您可以仅添加一个不可写的属性,如下所示:

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到属性中。

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

let a = Whatever.MyConst;

似乎为我工作。

我正在使用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-3

此文件中声明:

没有(有意地)没有直接的声明方式来定义原型数据属性(方法以外的类)或实例属性

这意味着它是故意这样的。

也许您可以在构造函数中定义一个变量?

constructor(){
    this.key = value
}

也可以Object.freeze在您的class(es6)/ constructor function(es5)对象上使用以使其不可变:

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

您可以通过冻结类将“常量”设置为只读(不可变)。例如

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";

这是您可以做的另一种方法

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

我做到了

class Circle
{
    constuctor(radius)
    {
        this.radius = radius;
    }
    static get PI()
    {
        return 3.14159;
    }
}

由于PI的值是从函数返回的值,因此可以防止PI的值被更改。您可以通过Circle.PI访问它。任何分配给它的尝试都可以简单地以类似于通过[]分配给字符串字符的方式放在地板上。

如果您愿意在函数和类语法之间进行混合和匹配,可以在类后声明常量(常量被“提升”)。请注意,Visual Studio Code将难以自动设置混合语法的格式(尽管它可以工作)。

class MyClass {
    // ...

}
MyClass.prototype.consts = { 
    constant1:  33,
    constant2: 32
};
mc = new MyClass();
console.log(mc.consts.constant2);    

您可以这样定义它:

class Foo {
  static MyConst = 200;

  myFunc() {
    const doubleConst = Foo.MyConst * 2;
  }
}

您可以使用import * as语法。尽管不是类,但它们是真实const变量。

Constants.js

export const factor = 3;
export const pi = 3.141592;

index.js

import * as Constants from 'Constants.js'
console.log( Constants.factor );
本文地址:http://javascript.askforanswer.com/zaies6leizhongshengmingjingtaichangliang.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!