在JavaScript继承模式中有5种,原型链继承、盗用构造函数,组合式继承,寄生组合式继承,es6 extends继承
在了解继承时需要明白JavaScript中 实例、原型对象、构造函数之间的关系
在JavaScript中 构造函数new出来的实例可理解为构造函数通过new关键字指向实例对象
而在每个实例中有__proto__属性可指向原型对象
构造函数可通过prototype指向原型对象,原型对象通过constructor指回构造函数,同样的实例也可通过constructor指向构造函数
stateDiagram-v2
原型对象 --> 构造函数
构造函数 --> 原型对象
构造函数 --> 实例
实例-->原型对象
实例-->构造函数
第一种 原型链继承
`
function Father() {
this.color = 'c'
}
function Son() {
}
//继承
Son.prototype = new Father()
const son = new Son()
console.log(son instanceof Father); //true
` 该方法就是修改Son原型对象的指向 将原型对象指向 father new出来的实例进行继承 该方法覆盖了Son的原型对象 所以其弊端必然是所有new Son new出来的对象在引用类型上与F实例共享同一内存空间(可与深浅拷贝相连接)
此时 son instanceof Father 将会是true
stateDiagram-v2
F原型对象 --> F构造函数
F构造函数 --> F原型对象
F构造函数 --> F实例
F实例-->F原型对象
F实例 -->F构造函数
S构造函数 --> F实例
S构造函数 --> S实例
S实例-->F实例
第二种盗用构造函数继承
`
function Father() {
this.color = 'c'
}
function Son() {
//继承
Father.call(this)
}
const son = new Son()
` 通过call、apply 方法改变this指向将Father构造函数的属性与方法复制回来 这将解决原型链上的内存共享问题 问题是不属于Father原型链
console.log(son instanceof Father); //false
第三种即为第一与第二种的结合
`
function Father() {
this.color = 'c'
}
function Son() {
//继承第二种方法模式
Father.call(this)
}
//继承 第一种方法模式
Son.prototype = new Father()
const son = new Son()
`