JavaScript 新语法详解:Class 的私有属性与私有方法
proposal-class-fields与proposal-private-methods定义了 Class 的私有属性以及私有方法,这 2 个提案已经处于 Stage 3,这就意味着它们已经基本确定下来了,等待被加入到新的 ECMAScript 版本中。事实上,最新的 Chrome 已经支持了 Class 私有属性。
那么,对于 Class 的私有属性与私有方法,它们究竟是什么呢?它们是怎样工作的?为什么要使用#符号来定义呢?
Class 的私有属性语法如下:
class Point { #x; #y; constructor(x, y) { this.#x = x; this.#y = y; } equals(point) { return this.#x === point.#x && this.#y === point.#y; } }
我们可以将其语法理解为 2 个部分:
- 定义 Class 私有属性
- 引用 Class 私有属性
定义 Class 私有属性
私有属性与公共属性的定义方式几乎是一样的,只是需要在属性名称前面添加#符号:
class Foo { publicFieldName = 1; #privateFieldName = 2; }
定义私有属性的时候也可以不用赋值:
class Foo { #privateFieldName; }
引用 Class 私有属性
引用私有属性也只需要使用#就好了。
class Foo { publicFieldName = 1; #privateFieldName = 2; add() { return this.publicFieldName + this.#privateFieldName; } }
其中,this.#可以简化,去掉 this 也没问题,下面两种写法是等价的:
method() { #privateFieldName; }
method() { this.#privateFieldName; }
在 Class 定义中引用 Class 实例的私有属性
对于私有属性,我们是不可以直接通过 Class 实例来引用的,这也是私有属性的本来含义。但是有一种情况除外,在 Class 定义中,我们可以引用 Class 实例的私有属性:
class Foo { #privateValue = 42; static getPrivateValue(foo) { return foo.#privateValue; } } Foo.getPrivateValue(new Foo()); // >> 42
其中,foo是Foo的实例,在 Class 定义中,我们可以通过 foo 来引用私有属性#privateValue。
Class 的私有方法
Class 的私有属性是提案proposal-class-fields的一部分,这个提案只关注 Class 的属性,它并没有对 Class 的方法进行任何修改。而 Class 的私有方法是提案proposal-class-fields的一部分。
Class 的私有方法语法如下:
class Foo { constructor() { this.#method(); } #method() { // ... } }
我们也可以将函数赋值给私有属性:
class Foo { constructor() { this.#method(); } #method = () => { // ... }; }
封装(隐藏)私有属性
我们不能直接通过 Class 实例引用私有属性,我们只能在 Class 定义中引用它们:
class Foo { #bar; method() { this.#bar; // Works } } let foo = new Foo(); foo.#bar; // Invalid!
另外,要做到真正的私有的话,我们应该无法检测这个私有属性是否存在,因此,我们需要允许定义同名的公共属性:
class Foo { bar = 1; // public bar #bar = 2; // private bar }
如果我们不允许公共属性与私有属性同名,我们则可以通过给同名的公共属性复制监测该私有属性是否存在:
foo.bar = 1; // Error: `bar` is private! (报错,说明私有属性存在)
不报错也行:
foo.bar = 1; foo.bar; // `undefined` (赋值失败,说明私有属性存在)
对于 subclass 应该同样如此,它也允许公共属性与私有属性同名:
class Foo { #fieldName = 1; } class Bar extends Foo { fieldName = 2; // Works! }
关于 Class 私有属性的封装,可以参考Why is encapsulation a goal of this proposal?。
为什么使用#符号?
很多人都有一个疑问,为什么 JS 不能学习其他语言,使用private来定义私有属性和私有方法?为什么要使用奇怪的#符号?
使用 private 的话,代码要舒服很多:
class Foo { private value; equals(foo) { return this.value === foo.value; } }
为什么不使用 private 来定义私有属性?
很多语言使用 private 来定义私用属性,如下:
class EnterpriseFoo { public bar; private baz; method() { this.bar; this.baz; } }
对于这些语言属性,私用属性和公共属性的引用方式是相同的,因此他们可以使用 private 来定义私有属性。
但是,对于 JavaScript 来说,我们不能使用 this.field 来引用私有属性(我接下来会解释原因),我们需要在语法层面上区分私有属性和公共属性。在定义和引用私有属性的时候,使用#符号,私有属性与公共属性可以很好地区分开来。
为什么引用私有属性的时候需要#符号?
引用私有属性的时候,我们需要this.#field,而不是this.field,原因如下:
- 因为我们需要封装私有属性,我们需要允许公共属性与私有属性同名,因此私有属性与公共属性的引用方式必须不一样。这一点我们在前文已经详述。
- 公共属性可以通过this.field以及this['field']来引用,但是私有属性不能支持this['field']这种方式,否则会破坏私有属性的隐私性,示例如下:
class Dict extends null { #data = something_secret; add(key, value) { this[key] = value; } get(key) { return this[key]; } } new Dict().get("#data"); // 返回私有属性
因此,私有属性与公共属性的引用方式必须不一样,否则会破坏this['field']语法。
- 私有属性与公共属性的引用方式一样的话,会导致我们每次都需要去检查属性是公共的还是私有的,这会造成严重的性能问题。
这篇文章遵循Creative Commons Attribution 4.0 International License。
参考
版权声明
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2019/04/23/javascript-class-private-field-and-private-method/
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
你学不懂C语言,是因为不懂编写C程序的7个步骤
编写一个C程序,这是一个很复杂的问题,面对复杂的问题,学会把它分解成若干个小问题,一个个小问题的解决,最后思路很清晰地解决掉这个“麻烦”。 一般情况下,我们把编写C程序分为7个步骤,懂得了后,编写程序就会有整体的思路,再也不像从前那样毫无头绪了。 1.定义程序的目标 定目标。明确这个程序是实现什么样的功能,你自己想要做出什么。明白你的程序需要哪些信息,像数学的公式、数学的单位转换信息。比如判断一个数是不是素数,“素数”在数学上是怎么界定的呢?这些都是你应该想清楚、弄明白的。不要一上来,就想着怎么用计算机语言表示。要从头到尾的想清楚你该怎么干。 2.设计程序 上一步已经对这个程序要完成什么样的任务,有了大概的认识。现在你要考虑的是用程序该如何完成它。把你的想法、思路往程序实现上逼近。 - 用户看到的整个程序界面应该是怎样的?目标用户是怎样的一类人?你需要花费多长的时间来解决掉这个程序? - 在程序中如何表示数据,用数组还是结构体呢?用什么方法处理数据?这一步也不需要想到具体的代码怎么写。 小编给大家推荐一个学习氛围超好的地方,C/C++交流企鹅裙:【8.7.0+九.六.三+2.5.1】适...
- 下一篇
大数据学习难度大吗?哪些人适合学习呢?
互联网的快速发展,科技的不断进步,使得数据呈爆炸式增长,而大数据的价值也开始被各个领域所重视,各大企业都开始纷纷高薪聘请大数据专业人才,所以,很多从事IT开发的人开始转行以谋求更好的发展,而对于那些没有编程基础的小白,学习大数据开发难度大吗? 对于进入进入新的行业,尤其是IT行业,每个人都会有担忧,这很正常,不论你有没有过经验都不免有些担忧。一方面,是因为你在此之前总听流言说编程如何如何难,工作是多么多么累,但它们就像老奶奶讲的吓人故事,是用来唬孩子们去学习社会科学而已。而另一方面,人们对于未知的事情总是充满着“恐惧”。其实无论是学习IT还是学习大数据开发,大家都是从0开始的,即使你没有基础也无需担心,毕竟大家最开始都是从小白度过的。 Java、python等等IT领域的开发人员如今都纷纷转型大数据,究其原因无非是大数据开发领域薪资高,且因为他们有编程基础,所以转型比较快。那么对于那些编程小白该如何去学习大数据开发呢?如何摆脱0基础的困境呢? 第一、小白学习大数据开发,心态很重要 对于陌生的知识领域,大家最开始接触的时候都不免有些困惑,会对自己产生怀疑,就像我们打游戏一样。刚开始总是操...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- MySQL8.0.19开启GTID主从同步CentOS8
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装