内容大多摘自[javascript高级程序设计第四版]第238页8.3继承 加深记忆

原型链

其基本思想就是通过原型继承多个引用类型的属性和方法。
构造函数、原型、实例的关系:每个构造函数都有一个原型对象,原型对象有一个属性constructor指回构造函数,而实例有一个内部指针指向原型。
如果原型是另一个类型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应的另一个原型也有一个指针指向另一个构造函数,这样就在市里和原型之间构造了一条原型链。这就是原型链的基本思想。
image.png
//学生实例
Human.prototype=new Student();
let s1=new Human();
console.log(s1.name);//小明
console.log(s1.studentWork());//学习
//教师实例
Human.prototype=new Teacher();
let t1=new Human();
console.log(t1.name);//小明
console.log(t1.teacherWork());//教学

原型和继承关系

原型和实例的关系可以通过instanceof 和 isPrototypeOf 来确定
instanceof
console.log(t1 instanceof Object);//true
console.log(t1 instanceof Teacher);//true
console.log(t1 instanceof Human);//true
从技术上来说:t1是Object、Teacher、HUman的实例。因为t1的原型链中包含了这些构造函数的原型。
更直白的讲:t1是Human的实例,Human的prorotype是Teacher的实例,Teacher的prototype是Object的实例。因此,t1的原型链上就一溜串的嵌套了多个原型链。
isPrototypeOf
console.log(Object.prototype.isPrototypeOf(t1));//true
console.log(Teacher.prototype.isPrototypeOf(t1));//true
console.log(Human.prototype.isPrototypeOf(t1));//true

关于原型链问题

1、原型中包含引用值时
image.png
2、子类型在实例化时不能给父类型构造函数传参

盗用构造函数

基本思路:在子类构造函数中调用父类构造函数。因为在特定上下文中执行代码的简单对象,所以可以使用apply 或 call 方法以新创建的对象为上下文执行构造函数。
image.png

不共享原型上的引用值

通过使用call / apply 方法,改变this,让每个Son实例对象都有自己的colors。

传递参数

相比于原型链,盗用构造函数的一个优点就是可以在子类构造函数中向父类构造函数传参。

盗用构造函数的问题

在这里,s1不能调用Student原型链上的studentWork方法,必须在构造函数中定义方法,因此,函数不能重用。
console.log('studentWork' in s1);//false,

组合继承

组合了原型链和盗用构造函数的模式。基本思路是使用原型链继承原型上的属性和方法,而通过盗用构造函数即成实例属性。这样既可以把方法定义在原型上实现重用,又可以让每个实例有自己的属性。
image.png