我想在中实现常量class
,因为在代码中找到常量是很有意义的。
到目前为止,我一直在使用静态方法实现以下变通方法:
class MyClass {
static constant1() { return 33; }
static constant2() { return 2; }
// ...
}
我知道有可能摆弄原型,但是很多人建议不要这样做。
有没有更好的方法在ES6类中实现常量?
我想在中实现常量class
,因为在代码中找到常量是很有意义的。
到目前为止,我一直在使用静态方法实现以下变通方法:
class MyClass {
static constant1() { return 33; }
static constant2() { return 2; }
// ...
}
我知道有可能摆弄原型,但是很多人建议不要这样做。
有没有更好的方法在ES6类中实现常量?
Answers:
您可以执行以下操作:
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;
然后,就像您说的那样,由于a 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
到属性中。
this.defineProperty(this, 'constant1', {...})
class Whatever {
static get MyConst() { return 10; }
}
let a = Whatever.MyConst;
似乎为我工作。
this.MyConst
从Whatever
实例内部使用它,因此始终必须这样编写: 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
stage-2
Object.freeze()
在类上调用吗?
在此文件中声明:
没有(有意地)没有直接的声明方式来定义原型数据属性(方法以外的类)或实例属性
这意味着它是故意这样的。
也许您可以在构造函数中定义一个变量?
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
尝试更改该类将给您一个软失败(不会引发任何错误,它只会无效)。
Object.freeze()
强制不变性,并且最近一直在使用它。只是不要忘记递归地应用它!
就像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;
}
这是您可以做的另一种方法
/*
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);
您可以创建一种使用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);
}
}
如果您愿意在函数和类语法之间进行混合和匹配,可以在类之后声明常量(常量被“提升”)。请注意,Visual Studio Code将难以自动设置混合语法的格式(尽管它可以工作)。
class MyClass {
// ...
}
MyClass.prototype.consts = {
constant1: 33,
constant2: 32
};
mc = new MyClass();
console.log(mc.consts.constant2);
我做到了
class Circle
{
constuctor(radius)
{
this.radius = radius;
}
static get PI()
{
return 3.14159;
}
}
由于PI的值是从函数返回的值,因此可以防止PI的值被更改。您可以通过Circle.PI访问它。任何分配给它的尝试都可以简单地以类似于通过[]分配给字符串字符的方式放在地板上。