为什么继承需要调用 super()
在子类 constructor
中必须调用 super
方法,因为子类没有自己的 this
对象,而是继承在父类的 this
对象,然后对其进行加工,而 super
就代表了父类的构造函数。
在下面的例子中,super 虽然代表了父类 A 的构造函数,但是返回的是子类 B 的实例,即 super 内部的 this 指的是 B,因此 super() 在这里相当于A.prototype.constructor.call(this, props)
。
// 父类
class People {
constructor(name) {
this.name = name
}
eat() {
console.log(`${this.name} eat something`)
}
}
// 子类
class Student extends People {
constructor(name, number) {
super(name)
this.number = number
}
sayHi() {
console.log(`姓名 ${this.name} 学号 ${this.number}`)
}
}
// 子类
class Teacher extends People {
constructor(name, major) {
super(name)
this.major = major
}
teach() {
console.log(`${this.name} 教授 ${this.major}`)
}
}
// 实例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()
xialuo.eat()
// 实例
const wanglaoshi = new Teacher('王老师', '语文')
console.log(wanglaoshi.name)
console.log(wanglaoshi.major)
wanglaoshi.teach()
wanglaoshi.eat()
原型
JavaScript
常被描述为一种基于原型的语言 —— 每个对象都有一个原型对象。
当试图访问一个对象属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
- 每个 class 都有一个显示原型
prototype
- 每个实例都有隐式原型
_proto_
- 每个
_proto_
指向对应 class 的prototype
基于原型的执行规则
- 获取属性 xialuo.name 或执行方法 xialuo.sayHi() 时
- 先在自身属性和方法寻找
- 如果找不到则自动去
_proto_
中查找
原型链
原型对象也可能拥有原型,并从中继承方法和属性,一层一层、依次类推。这种关系常常被称为原型链(prototype chain),它解释了为何一个对象会拥有定义在其它对象中的属性和方法。
```