js 实现继承的几种方式

方式1:Call实现

  • Parent1.call(this);会调用Parent方法,将属性绑定到child1上
function Parent1() {
  this.name = "parent1";
  this.f = function () {
    console.log("parent1");
  };
}
function Child1() {
  Parent1.call(this);
  this.type = "child1";
}

let child = new Child1();
child.f();
  • 缺点:无法继承Parent原型上的内容,因为相当于只是改变了一下this指向

方式2:原型链

function Parent2() {
  this.name = "parent2";
  this.play = [1, 2, 3];
}
function Child2() {
  this.type = "child2";
}
Child2.prototype = new Parent2();

let child1 = new Child2();
let child2 = new Child2();

child1.play.push(4);

console.log(child1.play, child2.play);
  • 缺点:多个实例的原型都是指向同一个对象,容易造成污染
    在这里插入图片描述

方式3:Call+原型链

  • 解决上一步实例属性污染的问题
  function Parent3 () {
    this.name = 'parent3';
    this.play = [1, 2, 3];
  }
  function Child3() {
    Parent3.call(this);
    this.type = 'child3';
  }
  Child3.prototype = new Parent3();
  //把父元素实例通过Call都绑定到自身实例上,实现隔离
  var s3 = new Child3();
  var s4 = new Child3();
  s3.play.push(4);
  console.log(s3.play, s4.play);

  • 缺点:Child3.prototype = new Parent3(); 会造成多运行一次构造函数

方式4:寄生组合继承

function Parent5() {
  this.name = "parent5";
  this.play = [1, 2, 3];
}
function Child5() {
  Parent5.call(this);
  this.type = "child5";
}
Child5.prototype = Object.create(Parent5.prototype);
//不加这个会使得child实例的constructor指向Parent5
Child5.prototype.constructor = Child5;

console.log(new Child5());


版权声明:本文为weixin_43294560原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。