JS的类特性,本质上还是原型继承模式的语法糖。

super

super指向[[HomeObject]]属性对象的原型。 :::info [[HomeObject]]是构造函数、方法内部特性,指向定义该方法的对象。 :::

  1. const obj = {
  2. foo() {
  3. return super.a //super指向的是定义该对象的原型。
  4. }
  5. }
  6. const proto = {
  7. a: 1
  8. }
  9. Object.setPrototypeOf(obj, proto);
  10. console.dir(obj.foo());

注释说明

组合式继承

组合起来使用原型链和引用构造函数。

function Supper(opt) {
  this.a = opt.a || 0;
}

Supper.prototype = {
  foo() { },
}

function Sub(opt) {
  Supper.call(this, opt);        //<-----引用父类构造函数
  this.b = opt.b;
}

Sub.prototype = new Supper();

var obj = new Sub({
  a: 1,
  b: 2
});

console.log(obj instanceof Supper);

image.png

:::info 组合继承的缺点就是父类的构造函数调用两次。实例的属性会遮蔽原型上的属性。 :::

圣杯模式

组合继承模式存在效率问题,会调用父类构造函数两次。把父类的原型对象剥离出来,使它成为一个中间对象的原型。

function SuperType(a) {
  this.a = a;
  this.name = [1, 2, 3, 4]
}

SuperType.prototype.foo = function (params) {
  console.log(1);
}

function SubType(opt) {
  SuperType.call(this, opt.a);
  this.b = opt.b
}

let inherite = function (subType, superType) {
  subType.prototype = Object.create(superType.prototype, {
    constructor: {
      value: subType   
    }
  })
}

inherite(SubType, SuperType);

//SubType的原型要重写,实现继承只会,才能增强原型对象。
SubType.prototype.bar = function () {}

const sub = new SubType({
  a: 1,
  b: 2
});
console.log(sub);

参考链接

https://www.cnblogs.com/xiaohuochai/p/5721552.html 一张图理解prototype、proto和constructor的三角关系