原型链和继承相关的事情

71 阅读1分钟

原型对象和构造函数有何关系

微信截图_20220328231035.png

原型链

JavaScript对象通过prototype指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条, 即原型链。

微信截图_20220328231143.png

  • 对象的 hasOwnProperty() 来检查对象自身中是否含有该属性
  • 使用 in 检查对象中是否含有某个属性时,如果对象中没有但是原型链中有,也会返回 true

JS如何实现继承

  • 借助call(构造函数继承)
function Parent1(){
    this.name = 'parent1';
  }
  function Child1(){
    Parent1.call(this);
    this.type = 'child1'
  }
  console.log(new Child1);

子类虽然能够拿到父类的属性值,但是问题是父类原型对象中一旦存在方法那么子类无法继承。

  • 借助原型链
function Parent2() {
    this.name = 'parent2';
    this.play = [1, 2, 3]
  }
  function Child2() {
    this.type = 'child2';
  }
  Child2.prototype = new Parent2();

  console.log(new Child2());

看似没有问题,父类的方法和属性都能够访问,但实际上有一个潜在的不足。

子类修改会影响父类,从而影响其他子类

  • 组合式继承
function Parent3 () {
    this.name = 'parent3';
    this.play = [1, 2, 3];
  }
  function Child3() {
    Parent3.call(this);
    this.type = 'child3';
  }
  Child3.prototype = new Parent3();
  var s3 = new Child3();
  var s4 = new Child3();
  s3.play.push(4);
  console.log(s3.play, s4.play);

存在的问题:Parent3的构造函数会多执行了一次(Child3.prototype = new Parent3();)

  • 组合继承的优化(寄生组合继承)
function Parent5 () {
    this.name = 'parent5';
    this.play = [1, 2, 3];
  }
  function Child5() {
    Parent5.call(this);
    this.type = 'child5';
  }
  Child5.prototype = Object.create(Parent5.prototype);
  Child5.prototype.constructor = Child5;
  • 原型链继承无法对父类进行传参,即Super功能,并且继承改变原型属性会连锁反应其他继承对象
  • 构造函数继承,不能继承到原型上的方法和属性
  • 组合式继承,缺点需要多次都new继承对象
  • 寄生式继承