Javascript 我怎样做一个“a”字;“公共静态字段”;在ES6班?
我正在创建一个Javascript类,我希望有一个类似Java的公共静态字段。以下是相关代码:Javascript 我怎样做一个“a”字;“公共静态字段”;在ES6班?,javascript,ecmascript-6,class-fields,Javascript,Ecmascript 6,Class Fields,我正在创建一个Javascript类,我希望有一个类似Java的公共静态字段。以下是相关代码: export default class Agent { CIRCLE: 1, SQUARE: 2, ... 这是我得到的错误: line 2, col 11, Class properties must be methods. Expected '(' but instead saw ':'. 看起来ES6模块不允许这样做。是否有办法获得所需的行为,或者我必须编写一个ge
export default class Agent {
CIRCLE: 1,
SQUARE: 2,
...
这是我得到的错误:
line 2, col 11, Class properties must be methods. Expected '(' but instead saw ':'.
看起来ES6模块不允许这样做。是否有办法获得所需的行为,或者我必须编写一个getter?在ECMAScript 6的当前草稿中(截至2015年2月),所有类属性都必须是方法,而不是值(请注意ECMAScript中的“属性”)在概念上与OOP字段类似,只是字段值必须是
函数
对象,而不是任何其他值,如数字
或对象
)
您仍然可以使用传统的ECMAScript构造函数属性说明符指定这些属性:
class Agent {
}
Agent.CIRCLE = 1;
Agent.SQUARE = 2;
...
使用访问器和“static”关键字创建“publicstaticfield”:
看看一个规范,-类定义-你会看到一些可疑的相关信息:)
ClassElement[收益率]:方法定义[?产量]
静态方法定义[?产量] 因此,从那里您可以遵循运行时语义:ClassDefinitionEvaluation-来仔细检查它是否真的做了看起来像的事情。具体而言,步骤20:
返回true 因此,
PropertyMethodDefinition
用“F”(构造函数,函数对象)作为参数调用,而“F”又反过来是参数
这至少在IETP(技术预览版)以及6to5和Traceur编译器中实现。为了充分利用静态变量,我采用了这种方法。更具体地说,我们可以使用它来使用私有变量,或者只使用公共getter,或者同时使用getter或setter。在最后一个案例中,它与上面发布的一个解决方案相同
var Url = (() => {
let _staticMember = [];
return class {
static getQueries(hash = document.location.hash) {
return hash;
}
static get staticMember(){
return _staticMember;
}
};
})();
Usages:
console.log(Url.staticMember); // [];
Url.staticMember.push('it works');
console.log(Url.staticMember); // ['it works'];
我可以创建另一个扩展Url的类,它成功了
我使用babel将我的ES6代码转换为ES5有一个由郭树瑜和Daniel Ehrenberg提出的第3阶段ECMAScript方案,旨在解决这个问题。除了第3阶段的建议外,您还可以执行以下操作:
class MyClass {
static myStaticProp = 42;
myProp = 42;
myProp2 = this.myProp;
myBoundFunc = () => { console.log(this.myProp); };
constructor() {
console.log(MyClass.myStaticProp); // Prints '42'
console.log(this.myProp); // Prints '42'
this.myBoundFunc(); // Prints '42'
}
}
上述内容相当于:
class MyClass {
constructor() {
this.myProp = 42;
this.myProp2 = this.myProp;
this.myBoundFunc = () => { console.log(this.myProp); };
console.log(MyClass.myStaticProp); // Prints '42'
console.log(this.myProp); // Prints '42'
this.myBoundFunc(); // Prints '42'
}
}
MyClass.myStaticProp = 42;
Google Chrome(和new Edge)在年开始支持这两项提案,相当于。Firefox支持自起的公共实例字段和自起的静态实例字段。有关更多信息,请访问
对于其他尚不支持这些功能的浏览器(特别是Safari),可以使用来对字段进行分类。这需要启用(或者您可以启用整个)
与@kangax声明getter的解决方案相比,该解决方案的性能也更高,因为在这里,属性是直接访问的,而不是通过调用函数 如果这个提议被接受,那么就有可能以一种更类似于传统面向对象语言(如Java和C)的方式编写JavaScript代码♯.
编辑:统一类字段建议现在处于第3阶段 编辑(2020年2月):静态类功能已拆分为不同的方案。谢谢@GOTO0
编辑(2021年3月):除了Safari之外,2020年4月之后发布的所有主要浏览器现在都支持此功能 @kangax的答案并没有模仿传统OOP语言的整个静态行为,因为您无法通过它的实例访问静态属性,比如
const-agent=new-agent;agent.CIRCLE;//未定义
如果您想像OOP一样访问静态属性,下面是我的解决方案:
class NewApp {
get MULTIPLE_VERSIONS_SUPPORTED() {
return this.constructor.MULTIPLE_VERSIONS_SUPPORTED; // Late binding for inheritance
}
}
NewApp.MULTIPLE_VERSIONS_SUPPORTED = true;
测试代码如下
classnewapp{
获取多个受支持的\u版本(){
console.log('this.constructor.name:',this.constructor.name);//后期绑定
返回this.constructor.MULTIPLE\u VERSIONS\u SUPPORTED;
}
}
//类可以访问静态属性
NewApp.MULTIPLE_VERSIONS_SUPPORTED=true;
const newApp=新的newApp;
//静态属性可以由其实例访问
console.log('newApp.MULTIPLE_VERSIONS_SUPPORTED:',newApp.MULTIPLE_VERSIONS_SUPPORTED);//真的
//继承权
类StandardApp扩展了NewApp{}
//静态属性可以被继承
console.log('StandardApp.MULTIPLE_VERSIONS_SUPPORTED:',StandardApp.MULTIPLE_VERSIONS_SUPPORTED);//真的
//静态属性可以被覆盖
StandardApp.MULTIPLE_VERSIONS_SUPPORTED=false;
const std=新标准应用程序;
console.log('std.MULTIPLE_VERSIONS_SUPPORTED:',std.MULTIPLE_VERSIONS_SUPPORTED);//false
您使用的是哪个ECMAScript 6引擎实现?@Dai注意,ES6类
语法只是传统JS构造函数和原型的语法糖。我认为您应该将这些属性放在原型上,而不是放在构造函数上,以便通过属性引用可以看到它们从实例中。@Pointy我推断OP试图存储常量以供参考(几乎像C#/.NETenum
)。@MattBrowne是的,但要明确的是类
语法也有某些细微的差异。例如,用Class.prototype.method=function(){}声明的方法
是可枚举的(在for in循环中可见),而类
方法是不可枚举的。对于正在查找的其他人,节点中还不支持静态访问器属性。:/至少从Node.js 6.x+开始,这是受支持的。请注意,如果使用flow,则必须在.fl中添加一行不安全。启用\u getters\u和\u setters=true
class NewApp {
get MULTIPLE_VERSIONS_SUPPORTED() {
return this.constructor.MULTIPLE_VERSIONS_SUPPORTED; // Late binding for inheritance
}
}
NewApp.MULTIPLE_VERSIONS_SUPPORTED = true;