admin管理员组文章数量:1604633
原文地址:SitePoint
无责任翻译:Sekai
这是微软的Web开发技术系列中的一部分,谢谢那些支持让SitePoint成为可能的伙伴们。
我将跟你们分享一系列的关于ECMAScript 6,分享我的心情,并且阐述这部分内容如何为你所用。我希望观众老爷们能像我一样享受这个过程。
首先,我在微软的Project Spartan(Sekai注:就是现在的Edge浏览器)项目里编写浏览器渲染引擎,这个项目为我们所知(爱?)多年的IE引擎做出了巨大的提升。我个人最喜欢的改进就是它对ECMAScript 6有了很大的支持。对我来说,这对编写庞大的Web应用有了巨大的好处。
根据这个兼容性图表和ES6 on status.modern.IE,在Project Spartan中,我们当前已经支持大约70%的ECMAScript 6的特性。
我爱Javascript,但是当使用在类似Babylon.js之类的巨大的应用中的时候,我更喜欢TypeScript,就是现在支持Angular 2的那个。原因就是JS(或者说ECMAScript 5)不包含所有的我写其他大项目的语法特性。比如我没法使用类和继承。
所以,事不宜迟,让我们直接一点:
创建一个类
Javascript是一个面向原型的语言,而且它可以使用ECMAScript 5模拟类和继承。
灵活的使用函数,我们能模拟处理类的时候的封装行为。一个技巧就是扩展一个对象的原型:
var Animal = (function () {
function Animal(name) {
this.name = name;
}
// Methods
Animal.prototype.doSomething = function () {
console.log("I'm a " + this.name);
};
return Animal;
})();
var lion = new Animal("Lion");
lion.doSomething();
这里,我们定义了一个包含属性
和方法
的类
。
这个类的构造器被它本身的函数所定义(Animal函数),这可以使它包含实例属性。使用原型(prototype)可以让我们定义那种可以作为实例方法的函数。
这当然可以正常运行,但是你得首先了解原型继承的相关知识,而且对于一个之前使用基于类的编程语言的程序猿来说,这种方式看起来十分怪异。更奇怪的是,Javascript有class的关键字,但是这玩意儿不做任何事。。。ECMAScript 6能让它工作起来,并且能让代码显得更短:
class AnimalES6 {
constructor(name) {
this.name = name;
}
doSomething() {
console.log("I'm a " + this.name);
}
}
var lionES6 = new AnimalES6("Lion");
lionES6.doSomething();
这个跟上面那段代码实际上是一样的,但他对要开始写一个类的程序猿更加友好。他们不再需要使用原型并且可以使用constructor
关键字来定义构造器。
此外,一些在ECMAScript 5中不存在的特性也被一并提出。比如你不能在没有用new
的情况下调用构造器。还有一点就是方法是不可以被枚举出来的。
另一个基于类的开发特性就是getter和setter方法,它们俩同样被ES6所支持。这可以更加明显的显示出方法本身是干嘛的:
class AnimalES6 {
constructor(name) {
this.name = name;
this._age = 0;
}
get age() {
return this._age;
}
set age(value) {
if (value < 0) {
console.log("We do not support undead animals");
}
this._age = value;
}
doSomething() {
console.log("I'm a " + this.name);
}
}
var lionES6 = new AnimalES6("Lion");
lionES6.doSomething();
lionES6.age = 5;
很方便吧?
但是这里我们使用了一个JS中一个很常见的小问题:Animal类中有个并不是真的私有的私有属性_age
。我之前对此写了这篇文章。
幸好,ECMAScript 6提供了一个新特性Symbol
来支持这个功能:
var ageSymbol = Symbol();
class AnimalES6 {
constructor(name) {
this.name = name;
this[ageSymbol] = 0;
}
get age() {
return this[ageSymbol];
}
set age(value) {
if (value < 0) {
console.log("We do not support undead animals");
}
this[ageSymbol] = value;
}
doSomething() {
console.log("I'm a " + this.name);
}
}
var lionES6 = new AnimalES6("Lion");
lionES6.doSomething();
lionES6.age = 5;
那么Symbol
是个啥?这是一个唯一且不变的数据类型,它可以用来标识对象的属性。如果你不知道这个Symbol,那么你就没法访问到这个属性。
这可以让这个变量更加“私有”。
或者说更加难以被访问到。Symbol对于变量名的唯一性是很有用的,但是唯一并不代表着私有。唯一只不过意味着如果你需要用到一个跟其他标识不一样的标识,就实例化一个新的Symbol吧!
但是这并不是真正意义上的私有,因为通过Object.getOwnPropertySymbols
,其他人就可以访问到你的Symbol属性了。
处理继承
当我们谈论类的时候,我们通常也喜欢提到继承。再次强调,同样可以在ES5中模拟继承,但是这是一个很复杂的活儿。
举个例子,让我们看看TypeScript是如何模拟继承的:
var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var SwitchBooleanAction = (function (_super) {
__extends(SwitchBooleanAction, _super);
function SwitchBooleanAction(triggerOptions, target, propertyPath, condition) {
_super.call(this, triggerOptions, condition);
this.propertyPath = propertyPath;
this._target = target;
}
SwitchBooleanAction.prototype.execute = function () {
this._target[this._property] = !this._target[this._property];
};
return SwitchBooleanAction;
})(BABYLON.Action);
太难读了,是不?
但是在ES6中看起来好多了:
var legsCountSymbol = Symbol();
class InsectES6 extends AnimalES6 {
constructor(name) {
super(name);
this[legsCountSymbol] = 0;
}
get legsCount() {
return this[legsCountSymbol];
}
set legsCount(value) {
if (value < 0) {
console.log("We do not support nether or interstellar insects");
}
this[legsCountSymbol] = value;
}
doSomething() {
super.doSomething();
console.log("And I have " + this[legsCountSymbol] + " legs!");
}
}
var spiderES6 = new InsectES6("Spider");
spiderES6.legsCount = 8;
spiderES6.doSomething();
多亏了extends
关键字,你可以用一个类派生出一个子类,并且通过使用super
关键字来访问父类。
通过使用这些优异的新特性,我们可以不必处理那些繁琐的原型语法就能创建类和使用继承。
为什么使用TypeScript会比之前更加要紧…
随着上述所有的特性被各类浏览器支持,我觉得用TypeScript生产Javascript代码变得更重要了。
首先,所有最新版本的TypeScript(1.4)已经开始支持ES6代码(通过使用let
和const
关键字),所以你只需要保留你原本的TypeScript代码,然后通过使用这些新功能来生产ES6代码。
但是,当你仔细观察一些TypeScript代码,你会发现这就像你在看一些没有类型的ES6代码一样。所以,现在学习TypeScript就是为了在未来更好的理解ES6的途径。
结语
Sekai注:翻译到这里有点后悔了。。
使用TypeScript,你现在就可以使用这一切,并生成跨浏览器的ES5代码。如果你想在浏览器中直接使用ES6,你可以升级到Win10,并且在Project Spartan中用它的渲染引擎测试。如果你不想这么做,你也可以用一些新的浏览器的特性,你也可以在这里用Project Spartan来进入一台Win10电脑。这在你的MacOS或者Linux中也是可以运行的。
当然,Project Spartan不是唯一支持标准ES6的浏览器,其他浏览器也正在跟进,你可以在这里追踪他们的进度。
支持ES6的Javascript的未来是非常光明的,并且老实说,我都等不及看到所有现代浏览器都支持ES6了!
本文标签: ECMAScript
版权声明:本文标题:理解ECMAScript 6:类和继承 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1728457103a1158800.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论