手写es5和es6实现原型继承

组合继承(为什么叫组合继承,组合继承就是构造函数继承和原型链继承的组合)

// 组合继承(只需要注意两点)
// 第一点:继承father的属性值。在Children构造函数中调用Father.call(this,val) (构造函数继承)
// 第二点:继承father的方法。let aa = new Father()之后可以aa.getVal(),让Children.prototype = aa,这样Children的实例就可以用到Father的方法了(把子类的prototype设置为父类的实例,也叫做原型链继承)
function Father(val){
    this.val = val
    this.father = 1111
}
function Children(val){
    Father.call(this,val) //构造函数继承解决原型链继承的缺点:解决了原型链继承造成的引用类型被所有实例共享的问题,但是缺点是function也是引用类型,这样的话就造程了每个子实例都会有相同的方法,造成了内存浪费
}
Children.prototype = new Father() //原型链继承
Father.prototype.getVal = function(payload = ''){
    console.log(this.val + payload)
}
let child = new Children("组合继承")
console.log(child)

运行出来的结果如下

 所以组合继承的缺点也是很明显,就是在继承父类函数的时候调用了父类构造函数,导致子类的原型上多了不需要的父类属性,造成了内存上的浪费

寄生组合继承

function Parent(value) {
  this.val = value
}
Parent.prototype.getValue = function() {
  console.log(this.val)
}

function Child(value) {
  Parent.call(this, value)
}
Child.prototype = Parent.prototype
Parent.prototype.constructor = Child
const child = new Child(1)

child.getValue() // 1
child instanceof Parent // true

es6 class继承

class Parent {
  constructor(value) {
    this.val = value
  }
  getValue() {
    console.log(this.val)
  }
}
class Child extends Parent {
  constructor(value) {
    super(value)
    this.val = value
  }
}
let child = new Child(1)
child.getValue() // 1
child instanceof Parent // true

class 实现继承的核心在于使用 extends 表明继承自哪个父类,并且在子类构造函数中必须调用 super,因为这段代码可以看成 Parent.call(this, value)

当然了,之前也说了在 JS 中并不存在类,class 的本质就是函数。

原文地址:https://www.cnblogs.com/gengzhen/p/15539191.html