目前在ES5中,我们很多人在框架中使用以下模式来创建类和类变量,这很舒服:
// ES 5
FrameWork.Class({
variable: 'string',
variable2: true,
init: function(){
},
addItem: function(){
}
});
在ES6中,你可以在本地创建类,但是没有选项可以有类变量:
// ES6
class MyClass {
const MY_CONST = 'string'; // <-- this is not possible in ES6
constructor(){
this.MY_CONST;
}
}
遗憾的是,上述方法不起作用,因为类只能包含方法。
我知道我能做到。myVar = true在构造函数…但我不想'垃圾'我的构造函数,特别是当我有20-30+参数为一个更大的类。
我想了很多方法来处理这个问题,但还没有找到一个好的。(例如:创建一个ClassConfig处理程序,并传递一个参数对象,该对象与类分开声明。然后处理程序将附加到类。我也在考虑以某种方式集成WeakMaps。)
你会有什么样的想法来处理这种情况?
正如Benjamin在他的回答中所说,TC39明确决定至少在ES2015中不包含这个功能。然而,共识似乎是他们将在ES2016中添加它。
语法还没有决定,但是ES2016已经有了一个初步的提议,允许你在一个类上声明静态属性。
多亏了巴别塔的魔力,你今天可以使用它。根据这些说明启用类属性转换,就可以开始了。下面是一个语法示例:
class foo {
static myProp = 'bar'
someFunction() {
console.log(this.myProp)
}
}
这个建议还处于非常早期的状态,所以准备好随着时间的推移调整您的语法。
2018年更新:
现在有一个第三阶段的提案——我期待着在几个月内让这个答案过时。
与此同时,任何使用TypeScript或babel的人都可以使用以下语法:
varName = value
在类声明/表达式体中,它将定义一个变量。希望在几个月或几周后,我能够发布更新。
更新:Chrome 74现在船与此语法工作。
ES wiki中关于ES6提案的注释(最大最小类)注意到:
(有意地)没有直接的声明性方法来定义原型数据属性(方法除外)类属性或实例属性
类属性和原型数据属性需要在声明之外创建。
在类定义中指定的属性被赋予与出现在对象字面量中相同的属性。
这意味着你的要求已经被考虑过了,并且被明确地否决了。
但是…为什么?
好问题。TC39的好人希望类声明能够声明和定义类的功能。不是它的成员。ES6类声明为用户定义了它的契约。
记住,类定义定义了原型方法——在原型上定义变量通常不是你要做的事情。
当然,你可以使用:
constructor(){
this.foo = bar
}
在构造函数中。另见共识摘要。
ES7及以上版本
ES7的一个新提议正在研究中,它允许通过类声明和表达式来实现更简洁的实例变量——https://esdiscuss.org/topic/es7-property-initializers
只是补充一下本杰明的答案——类变量是可能的,但你不会使用原型来设置它们。
对于一个真正的类变量,你应该像下面这样做:
class MyClass {}
MyClass.foo = 'bar';
在类方法中,该变量可以通过this.constructor.foo(或MyClass.foo)访问。
这些类属性通常不能被类实例访问。即MyClass。foo给出'bar'但新的MyClass()。Foo没有定义
如果你也想从实例中访问你的类变量,你必须另外定义一个getter:
class MyClass {
get foo() {
return this.constructor.foo;
}
}
MyClass.foo = 'bar';
我只在Traceur上测试过这个功能,但我相信它在标准实现中也能发挥同样的作用。
JavaScript实际上没有类。即使在ES6中,我们看到的是基于对象或原型的语言,而不是基于类的语言。在任何函数X(){}中,X.prototype.constructor都指向X。
当在X上使用new操作符时,将创建一个继承X.prototype的新对象。新对象中任何未定义的属性(包括构造函数)都将从那里查找。我们可以把这看作是生成对象和类属性。