前言
了解完ES5实现继承,接着就是ES6实现继承了。如果一定要问为什么ES6又有继承,说明ES5的实现方式有很大提升空间。
一、类的使用
1. class定义类
ES6标准中使用class关键字定义类。类的本质是构造函数、原型链的语法糖。
class Person {
}
var p = new Person()
Java:“打钱!!!”
2. class类中的内容
2.1 类中的方法
2.1.1 constructor方法(构造函数)
当通过new关键字调用Person类,默认调用class中的constructor方法。
- 每个类
只有一个构造函数,如果包含多个构造函数,会抛出异常。
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
}
var p = new Person('why', 18)
console.log(p.__proto__ === Person.prototype) // true
使用new操作符操作类的过程:
- 在内存中创建一个新的对象(空对象)。
- 这个
对象内部的[[prototype]]属性会被赋值为该类的prototype属性。 - 构造函数内部的
this,指向创建出来的新对象。 - 执行构造函数的内部代码(函数体代码)。
- 如果构造函数没返回非空对象,则返回创建出来的新对象。
2.1.2 实例方法
在类中定义。本质上是放在Person.prototype上,可以被多个实例共享。
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
// 实例方法
running () {}
}
var p = new Person('why', 18)
p.running()
2.1.3 getter/setter方法(访问器方法)
访问器的作用:监听属性什么时候被访问,可以对属性做设置。
class Person {
constructor(name, age) {
this._name = name
this.age = age
}
set name (value) {
this._name = value
}
get name () {
return this._name
}
}
var p = new Person('why', 18)
p.name = '11'
console.log(p);
2.1.4 静态方法(类方法)
可以直接使用类来执行,不需要有类的实例。使用static关键字来定义。
class Person {
constructor(name, age) {
this._name = name
this.age = age
}
static sleeping () {
console.log('static sleep');
}
}
var p = new Person('why', 18)
Person.sleeping()
2.2 类和构造函数的区别
class定义的类,不能作为一个普通函数进行调用。
3. extends实现继承
ES6使用extends关键字实现继承。
class Person {
}
class Student extends Person {
}
这也太简单了吧!!!再也不用记什么借用、寄生、原型式......呕!!!
// 举个栗子
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
running () {}
}
class Student extends Person {
constructor(name, age, sno, score) {
super(name, age)
this.sno = sno
this.score = score
}
learning () {}
}
class Teacher extends Person {
constructor(name, age, title) {
super(name, age)
this.title = title
}
teaching () {}
}
一句话总结:在ES6中使用class关键字定义类,使用extends关键字实现子类继承父类的属性和方法。
3.1 super关键字
- 执行
super.method(...)来调用父类方法。 - 执行
super(...)来调用父类的constructor方法。只能在子类的constructor方法中调用super(...)。 - 使用位置:
子类构造函数、实例方法、静态方法。就是在定义子类时,子类中的方法内都可以调用super函数。 - 在子类的构造函数中使用
this或者返回默认对象之前,必须先调用super(...)。
4. 自定义类继承内置类
内置类:Array、Object、Date等等。场景就是扩展内置类,自定义一些属性或者方法。
两种继承方式:
- 创建一个类
继承自内置类。 - 直接对内置类的
prototype追加内容。
5. 类的混入Mixin
类只支持单继承,也就是只有一个父类。要继承多个类就要使用混入(Mixin)的方式。
function mixinAnimal (BaseClass) {
return class extends BaseClass {
eating () {}
}
}
function mixinRunner (BaseClass) {
return class extends BaseClass {
running () {}
}
}
class Bird {
flying () {}
}
class NewBird extends mixinAnimal(mixinRunner(Bird)) {
}
var newBird = new NewBird()
newBird.running()
newBird.eating()
newBird.flying()
Me: 'I'm ok!'
二、使用Babel查看ES6转ES5源码
// ES6代码
class Person {
constructor (name, age) {
this.name = name
this.age = age
}
studying () {
console.log(this.score);
}
}
class Student extends Person {
constructor (name, age, sno, score) {
super(name, age)
this.sno = sno
this.score = score
}
}
var stu = new Student('why', 18, 111, 100)
stu.studying()
难道你对extends的源码不好奇?我不好奇。
三、总结
面试官:“你怎么处理继承?”
我:“在ES6中使用class关键字定义类,使用extends关键字实现子类继承父类的属性和方法。”