class 类
在此之前,ECMAScript 中都是通过定义函数以及函数的原型对象来实现的类型。如下代码所示:
function Person(name) {
this.name = name
}
如果需要这个类型所有实例之间共享一些成员,可以借助于函数对象的 prototype
来实现。如下代码所示:
Person.prototype.say = function () {
console.log(`hi, my name is ${this.name}`)
}
自从 ECMAScript2015 开始,就可以使用 class
关键字来声明一个类型。这种独立定义类型的语法相比于之前函数的方式要更容易理解一点,结构也会更加清晰一些。如下代码所示:
class Person {
}
这种语法和一些传统的面向对象语言当中的 class
是非常相似的。如果说需要在构造函数当中做一些额外的逻辑,可以添加一个叫做 constructor()
方法,这个方法就是当前类型的构造函数。如下代码所示:
class Person {
constructor (name) {
this.name = name
}
}
如果想要为这个类型定义一些实例方法,只需要在这个类型里面添加对应的方法成员就可以了。如下代码所示:
class Person {
constructor(name) {
this.name = name
}
say() {
console.log(`hi, my name is ${this.name}`)
}
}
完成之后,同样可以使用 new
关键字来创建这个类型的实例对象。如下代码所示:
const p = new Person('前端课湛')
p.say()
上述代码的运行结果如下:
hi, my name is 前端课湛
静态成员
在类型当中的方法,一般分为实例方法和静态方法。实例方法就是需要通过这个类型构造的实例对象调用,而静态方法则是直接通过类型本身调用。
在 ECMAScript2015 之前想要实现静态方法就是直接在构造函数对象上挂载方法实现,因为在 JavaScript 语言当中函数也是对象,它也可以添加一些方法成员。
而在 ECMAScript2015 中新增了添加静态方法的 static
关键字。如下代码所示:
class Person {
constructor(name) {
this.name = name
}
say() {
console.log(`hi, my name is ${this.name}`)
}
static create(name) {
return new Person(name)
}
}
const p = Person.create('前端课湛')
p.say()
上述代码的运行结果如下:
hi, my name is 前端课湛
这里需要注意的是,因为静态方法是挂载到类型上面的,所以说在静态方法内部的 this
就不会指向某一个实例对象,而是当前的类型。
类的继承
继承是面向对象中一个非常重要的特性,通过继承这种特性就能够抽象出来相似类型之间重复的部分。在 ECMAScript2015 之前,大多数情况都会使用原型的方式实现继承。而在 ECMAScript2015 中新增了一个专门用于实现继承的 extends
关键字。如下代码所示:
class Person {
constructor(name) {
this.name = name
}
say() {
console.log(`hi, my name is ${this.name}`)
}
}
class Student extends Person {
constructor(name, number) {
super(name)
this.number = number
}
hello() {
super.say()
console.log(`my school number is ${this.number}`)
}
}
const s = new Student('大叔', 100)
s.hello()
从上述代码可以看到,在子级类型当中可以通过 super
关键字指向父级类型,从而调用父级类型的方法成员。上述代码的运行结果如下:
hi, my name is 大叔
my school number is 100
通过 extends 关键字实现的继承要比使用原型实现的继承更方便一点,也更清楚一点。