理解Ecmascript 6中的类和继承

545 查看

分享一系列关于 ECMAScript 6 的文章,分享我对它的热爱并解释如何让它为你所用。希望你在阅读的时候能和我写作的时候一样享受快乐。

首先,我是在微软负责 Spartan 浏览器 渲染引擎项目,该引擎是在我们多年来熟悉的(并爱上的?)Internet Explorer  引擎的基础上,做出巨大改进。我最喜欢该引擎的特性是支持大部分 ECMAScript 6。对我而言,这对编写大型 web 应用程序会带来巨大好处。

到目前为止,已有将近 7 成 ECMAScript 6 特性在 Spartan 项目上得到支持,通过 http://kangax.github.io/compat-table/es6/ 和 ES6 on status.modern.IE 可查看相关信息。

我喜欢 JavaScript,但运用在大型项目上,如 Babylon.js,我更情愿用 TypeScriptAngular 2 现在正是基于它实现的。没用 JavaScript 的原因是它没有我习惯使用其它语言编写大型程序的所有语法特性比如类和继承。

所以事不宜迟,让我们开始吧。

创建类

JavaScript 是一种面向原型的语言,并在 ECMAScript 5 中,能模拟类和继承。

在 JavaScript 中,灵活的函数允许我们模拟常用于处理类的封装。通过这个技巧,能扩展对象的原型。

在上面的代码中,定义了一个带有“属性”和“方法”的“类”。

这个构造器通过函数(函数 Animal)定义,并能实例化属性。通过使用原型,可定义能被实例化的函数。

而问题是,假设你了解原型继承和一些基于类继承的语言,你会感到很混乱。奇怪的是,JavaScript 有 class 关键字,却不能做任何事。而现在 ECMAScript 6 用上它了,这使我们可以写更短的代码:

运行结果和前面的一样,但对于习惯于写类的开发者来说,更易编写和阅读。因为这不需要原型,并且能使用 “constructor” 关键字定义构造器。

此外,类引入了一些 ECMAScript 5 新的语法。例如,必须通过 new 调用构造函数,或者不能用 new 尝试去构造类方法。另一个改变是,方法都是不可枚举的。

有趣的地方是:两个版本可同时共存使用。

归根结底,即使用 new 关键字实例化一个添加在原型的函数。“方法”在这里仅仅是对象的一个函数属性。

另一个基于类开发的核心特性是,getter 和 setter 都在 ECMAScript 6 得到支持。这使方法的用途变得更加明显:

十分方便,对吧?

但这会看到一个 JavaScript 的常规警告:“不是真正私有的”私有成员(_age)。我之前在这个主题 里写了一篇关于这个问题的文章。

辛亏,现在有一个更好的、新的 ECMAScript 6 特性来完成这个事情:symbols (符号):