JS基于原型的继承理解

原型&原型链

JavaScript 只有一种结构:对象。每个对象(object)都有一个私有属性指向另一个名为原型(prototype)的对象。原型对象也有一个自己的原型,层层向上直到一个对象的原型为 null。根据定义,null 没有原型,并作为这个原型链(prototype chain)中的最后一个环节。

JavaScript 对象是动态的属性(指其自有属性)“包”。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

student._proto_ === Student.prototype 
// 隐式原型 显示原型
class Person{
constructor(name){
this.name = name;
}
drink(){
console.log('喝水');
}
}
class Teacher extends Person{
constructor(name,subject){
super(name);
this.subject = subject;
}
teach(){
console.log(`我是$(this.name),教$(this.subject)。`)
}
}
const teacher = new Teacher('哈默','前端开发');
console.log('teacher',teacher);
teacher.teach();
teacher.drink();

代码对应原型链如图:

image-20231106141020167

补充

super关键字:

super 关键字用于访问和调用一个对象的父对象上的函数。在构造函数中使用时,super关键字将单独出现,并且必须在使用 this 关键字之前使用。super 关键字也可以用来调用父对象上的函数。

语法:

super(arguments);  // 调用父构造函数
super.parentMethod(arguments); // 调用父方法

在类中使用super实例:

class Polygon {
constructor(height, width) {
this.name = 'Rectangle';
this.height = height;
this.width = width;
}
sayName() {
return 'Hi, I am a ' + this.name + '.';
}
get area() {
return this.height * this.width;
}
set area(value) {
this._area = value;
}
}

class Square extends Polygon {
constructor(length) {
// 这里,它调用父类的构造函数的,
// 作为 Polygon 的 height, width
super(length, length);

this.height; // 需要放在 super 后面,不然引发 ReferenceErro

// 注意:在派生的类中,在你可以使用'this'之前,必须先调用 super()。
// 忽略这,这将导致引用错误。
this.name = 'Square';
}
}