js中的继承与 原型对象、实例、构造函数三者的关系

103 阅读1分钟

在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()

`