一步,一步前進の一步
ES6深入浅出之Classes。翻译的同时乱加个人见解,强烈推荐阅读原作者的文章,言简意赅。es6-classes-in-depth
类
语法本质
JS 是基于原型的语言,那么ES6里的classes
是什么东西?classes 是原型继承的语法糖——主要是用来勾引不太理解 JS 原型链语法的其他语言使用者。ES6有好多新的特性本质上就是语法糖
,classes也不例外。我会向你证明 classes 是语法糖,因为classes 的语法很容易使用 ES5的语法实现出来,classes 并不是JS 语法的一个变革,它存在的目的仅仅是使原型继承
变得简单。
ES5
和 ES6
的类实现对比
那么,我假设你已经很好的理解了原型继承的原理,毕竟你已经在阅读ES6这么高级的东西了。下面代码定义车的类,可被实例化,加油,移动。
function Car () {
this.fuel = 0;
this.distance = 0;
}
Car.prototype.move = function () {
if (this.fuel < 1) {
throw new RangeError('Fuel tank is depleted')
}
this.fuel--
this.distance += 2
}
Car.prototype.addFuel = function () {
if (this.fuel >= 60) {
throw new RangeError('Fuel tank is full')
}
this.fuel++
}
使用下面的代码使车跑起来吧:
var car = new Car()
car.addFuel()
car.move()
car.move()
// <- RangeError: 'Fuel tank is depleted'
上面的代码都是 ES5,那么 ES6该如何实现呢?类声明的书写和对象的写法十分相似,花括号前面只多了 class Name
,类方法我们将采用方法名简写的形式。contrustor 是构造函数,可在里面初始化我们想初始化的东西。
class Car {
constructor () {
this.fuel = 0
this.distance = 0
}
move () {
if (this.fuel < 1) {
throw new RangeError('Fuel tank is depleted')
}
this.fuel--
this.distance += 2
}
addFuel () {
if (this.fuel >= 60) {
throw new RangeError('Fuel tank is full')
}
this.fuel++
}
}
需要强调的是:类和对象声明写起来是很像,但是在类中属性及方法间是不允许使用逗号
分隔的,分号倒是没问题。
类静态方法
大多数情况下,类是有静态方法
的。回想一下我们日常使用最多的数组,常见的实例方法有.filter
、 .reduce
、 .map
,类方法有Array.isArray
。ES5中添加类方法十分容易(类方法和静态方法是同一个东西):
// es5
function Car () {
this.topSpeed = Math.random()
}
Car.isFaster = function (left, right) {
return left.topSpeed > right.topSpeed
}
在 ES6的 class 语法中,我们可以使用static
关键字修饰方法,进而得到静态方法。
class Car {
constructor () {
this.topSpeed = Math.random()
}
static isFaster (left, right) {
return left.topSpeed > right.topSpeed
}
}
那么既然说classes
是语法糖,那我们同样可以使用如下方式实现静态方法:
class Car {
constructor () {
this.topSpeed = Math.random()
}
}
Car.isFaster = (left, right) => {
return left.topSpeed > right.topSpeed;
}
目前 ES6还不支持使用 static 来修饰属性,若想获得类的静态属性,该如何实现?请参考上面代码,给出答案,可以在评论区做答?
提供另一种思路使用 get
、set
实现静态属性,try it.
类继承
classes
不仅使类声明变得简单,它让继承变得更加可读,容易。ES6中的 extends
支持从基类衍生出更具个性化的子类。众所周知,特斯拉较其他汽车比较省油,特斯拉是啥。那么,我们基于上面的 Car来实现Tesla
类。下面的代码的意思是 Tesla 类继承 Car,并复写 Car 爸爸
的 move 方法进而行驶更远的距离。
class Tesla extends Car {
move () {
super.move()
this.distance += 4
}
}
var car = new Tesla()
car.addFuel()
car.move()
console.log(car.distance)
关于继承,有一点需要特别注意,当子类想要实现特有的构造函数 constructor 时,首行必须使用 super(…)调用父类的构造函数,先得到父类的this作为自己的 this。此处的理论有一点点深,有机会再讲。
class Car {
constructor (speed) {
this.speed = speed
}
}
class Tesla extends Car {
constructor (speed) {
// 不调用 super 的话,会报错
super(speed * 2)
// 做其他初始化工作 。。。
}
}
知识点总结
- classes 只是语法糖,使类声明和继承书写变的容易
- 子类 constructor 要么有,要么首行调用super
- 静态方法
static
修饰 - 子类会覆盖父类的同名方法,但是可以使用 super.xxxx 方法调用父类方法。
一步本人作了个决定,把Nicolás Bevacqua es6-in-depth都给翻译了,如果侵权了我就立刻删除🤞。不知道该如何快速提高个人技能,人还懒。望大家监督,各位前辈给指条进步明路也可以。
🌚 前端学习QQ群: 538631558 🌚
【开发环境推荐】
Cloud Studio 是基于浏览器的集成式开发环境,支持绝大部分编程语言,包括 HTML5、PHP、Python、Java、Ruby、C/C++、.NET 小程序等等,无需下载安装程序,一键切换开发环境。 Cloud Studio提供了完整的 Linux 环境,并且支持自定义域名指向,动态计算资源调整,可以完成各种应用的开发编译与部署。