继承分类

1.类式继承

原理:重写子类的原型,代之以父类的实例。

function Father(name) {
  this.faName = name
  this.faAge = 28
  this.friend = ['zs','ls','ww']
}

const a = new Father('wumao')

function Son(name) {
  this.sonName = name
  this.sonAge = 6
}
Son.prototype = new Father()

const b = new Son('liumao')
const c = new Son('qimao')
console.log(a);
console.log(b);
console.log(b.faAge); // 28

b.faAge = 29
b.friend.push('lm')
console.log(b.friend); // [ 'zs', 'ls', 'ww', 'lm' ]
console.log(c.faAge); // 28
// 缺点:当引用数据类型被修改 会影响到他所有的实例对象
console.log(c.friend); //[ 'zs', 'ls', 'ww', 'lm' ]


console.log(a instanceof Father); // true
console.log(b instanceof Father); // true
console.log(b instanceof Son); // true

缺点

  1. 当继承父类的时候,当有复杂数据类型的时候,修改复杂类型的数据时,会修改到所有的实例对象
  2. 无法传递参数,当创建子类型实例的时候,不能向父类构造函数中传递参数

2.构造函数式继承(经典继承)

原理:通过之类的内部通过call,apply去执行要继承的父类

function Father(name) {
  this.faName = name
  this.faAge = 28
  this.friend = ['zs', 'ls', 'ww'],
  Father.prototype.hello = 'hello world'
}


function Son(name) {
  Father.call(this,name)
  this.sonName = name
  this.sonAge = 6
}

const a = new Son('haha')
console.log(a);

console.log(a instanceof Father); //false
console.log(a instanceof Son); //true
console.log(a.hello); // undefined

缺点

  1. 不能通过instanceof检测到继承来自父类
  2. 不能使用父类的原型上的属性和方法

3.组合式继承

既然类式继承和构造函数式继承都有缺陷,那我们就进行组合一起

function Father(name) {
  this.faName = name
  this.faAge = 28
  this.friend = ['zs', 'ls', 'ww'],
  Father.prototype.hello = 'hello world'
}


function Son(name) {
  Father.call(this,name)
  this.sonName = name
  this.sonAge = 6
}
Son.prototype = new Father()
const a = new Son('haha')
console.log(a);

console.log(a instanceof Father); //true
console.log(a instanceof Son); //true
console.log(a.hello); // hello world

缺点

  1. 父类的构造函数被调用了两次,显得多余
  2. 创建的实例对象会不仅在对象上创建一份,还会在原型上也创建一份

4.原型式继承

这个本质上其实是对一个对象的浅拷贝,暴露的问题也是,不能传入参数以及引用类型会共享

function createObject(obj) {
  function F() {

  }
  F.prototype = obj;
  return new F()
}
var person = {
  name: "wumao",
  friends: ["liumao", "qimao"]
};


const a =  createObject(person)
const b =  createObject(person)

缺点:

  1. 子类实例无法传入参数
  2. 父类的引用会被所有子类所共享

5.寄生式继承

寄生式继承和原型式继承差不了太多,
它依托于一个内部对象而生成一个新对象,因此称之为寄生。

var person = {
  name: 'wumao',
  age: 18
}

function createObj(obj) {
  const o = Object.create(obj)
  o.__proto__.who = function () {
    console.log(this.name);
  }
  return o
}

const c = createObj(person)

c.who()
console.log(c.name);

6.寄生组合式继承

function inherit(child, parent) {
  const p = Object.create(parent.prototype)
  child.prototype = Object.assign(child.prototype, p)
  //还原被污染的constructor
  child.prototype.constructor = child
}

// 父类
function Father(name) {
  this.fatherName = name
}
Father.prototype.who = function () {
  console.log(this.name);
}

// 子类
function Son(wife, fatherName) {
  Father.call(this, fatherName)  //把属性继承过来
  this.wife = wife
  this.age = 22
}

inherit(Son, Father) //把原型继承过来

const newObj = new Son('gaga', 'haha')
console.log(newObj.fatherName);

好处

  1. 继承的属性没有在原型链上.因此不会共用一个属性
  2. 子类可以动态传入参数
  3. 父类的构造函数只执行了一次
Last modification:March 10, 2021
If you think my article is useful to you, please feel free to appreciate