JavaScript:公共和私有类字段

一些建议通过新功能扩展了JavaScript中现有的类语法。 本文介绍了V8 v7.2和Chrome 72中公共类字段以及即将发布的私有字段的新语法。


这是实例化IncreasingCounter类的代码示例:


const counter = new IncreasingCounter(); counter.value; // logs 'Getting the current value!' // → 0 counter.increment(); counter.value; // logs 'Getting the current value!' // → 1 

请注意,在返回值之前,访问值会执行一些代码(向日志输出消息)。 现在问自己:如何在JavaScript中实现此类?


ES2015课程


以下是如何使用ES2015语法实现IncreasingCounter类的示例:


 class IncreasingCounter { constructor() { this._count = 0; } get value() { console.log('Getting the current value!'); return this._count; } increment() { this._count++; } } 

该类提供了一个吸气剂和一种在原型中增加值的方法。 更奇怪的是,该类具有一个构造器,该构造器可以初始化_count属性并将其初始值设置为0。 实际上,这不是私有属性,并且该语义未在语言本身中定义。


 const counter = new IncreasingCounter(); counter.value; // logs 'Getting the current value!' // → 0 // Nothing stops people from reading or messing with the // `_count` instance property. counter._count; // → 0 counter._count = 42; counter.value; // logs 'Getting the current value!' // → 42 

类公共领域


公共字段的新语法简化了类定义:


 class IncreasingCounter { _count = 0; get value() { console.log('Getting the current value!'); return this._count; } increment() { this._count++; } } 

现在,在类的开头简洁地声明了_count属性。 我们不再需要仅定义一些字段的构造函数。 太好了!


但是, _count仍然是公共财产。 在此特定示例中,我们希望防止直接访问此字段。


私人班级领域


这是私人领域进行救援的地方。 专用字段的新语法类似于公用字段的语法,不同之处在于, 您使用符号将它们标记为专用 。 您可能会认为只是字段名称的一部分:


 class IncreasingCounter { #count = 0; get value() { console.log('Getting the current value!'); return this.#count; } increment() { this.#count++; } } 

私有字段在类主体之外不可用:


 const counter = new IncreasingCounter(); counter.#count; // → SyntaxError counter.#count = 42; // → SyntaxError 

静态特性


类字段语法可用于创建公共和私有静态属性和方法,如下所示:


 class FakeMath { // `PI` is a static public property. static PI = 22 / 7; // Close enough. // `#totallyRandomNumber` is a static private property. static #totallyRandomNumber = 4; // `#computeRandomNumber` is a static private method. static #computeRandomNumber() { return FakeMath.#totallyRandomNumber; } // `random` is a static public method (ES2015 syntax) // that consumes `#computeRandomNumber`. static random() { console.log('I heard you like random numbers…') return FakeMath.#computeRandomNumber(); } } FakeMath.PI; // → 3.142857142857143 FakeMath.random(); // logs 'I heard you like random numbers…' // → 4 FakeMath.#totallyRandomNumber; // → SyntaxError FakeMath.#computeRandomNumber(); // → SyntaxError 

简化子类的工作


当使用引入其他字段的子类时,新的类字段语法的好处变得更加明显。 想象以下动物基类:


 class Animal { constructor(name) { this.name = name; } } 

要创建向实例添加新属性的Cat子类,您以前需要在创建此属性之前调用super()来调用Animal基类的构造函数:


 class Cat extends Animal { constructor(name) { super(name); this.likesBaths = false; } meow() { console.log('Meow!'); } } 

有很多样板代码只是用来表明猫们真的不喜欢洗澡。 幸运的是,新的类字段语法消除了对super()的笨拙调用来定义此构造函数的需要:


 class Cat extends Animal { likesBaths = false; meow() { console.log('Meow!'); } } 

合计


从V8 v7.2和Chrome 72开始,可以使用公共类字段。我们计划很快发布私有类字段。

Source: https://habr.com/ru/post/zh-CN438202/


All Articles