Skip to content

继承

原型链继承

子类的原型对象是父类的实例对象

优点:

  • 简单易懂 缺点:
  • 1 实例化子类时,没办法向父类的构造函数传值
  • 2 所有子类实例共享一个父类,当某个子类修改了父类的属性时,其他子类也会受到影响
js
function Parent() {
    this.name = 'parent';
}

Parent.prototype.getName = function () {
    return this.name;
}

function Child() {
    this.name = 'child';
}

Child.prototype = new Parent();
function Parent() {
    this.name = 'parent';
}

Parent.prototype.getName = function () {
    return this.name;
}

function Child() {
    this.name = 'child';
}

Child.prototype = new Parent();

构造函数继承

在子类的构造函数中调用父类的构造函数

优点:

  • 解决了原型链继承中,所有子类实例共有一个父类以及实例化子类时向父类传参的问题

缺点:

  • 没办法继承父类原型上的属性和方法,父类的方法和属性会被重复创建
js
function Parent() {
    this.name = 'parent';
}

Parent.prototype.getName = function () {
    return this.name;
}

function Children () {
    Parent.call(this);
}
function Parent() {
    this.name = 'parent';
}

Parent.prototype.getName = function () {
    return this.name;
}

function Children () {
    Parent.call(this);
}

组合继承

子类构造函数调用了父类,子类的原型对象指向父类的实例对象

优点:

  • 解决了构造函数继承无法继承父类原型上的属性和方法的问题

缺点:

  • 实例化子类时,会重复调用父类的构造方法
js
function Parent () {
    this.name = 'Parent';
}

Parent.prototype.getName = function () {
    return this.name;
}

function Children () {
    Parent.call(this);
}

Children.prototype = new Parent();
Children.prototype.constructor = Children;
function Parent () {
    this.name = 'Parent';
}

Parent.prototype.getName = function () {
    return this.name;
}

function Children () {
    Parent.call(this);
}

Children.prototype = new Parent();
Children.prototype.constructor = Children;

寄生组合继承

优点:

  • 解决了组合继承中,实例化子类时重复调用父类构造函数的问题

缺点:

  • 相对复杂
js
function Parent () {
    this.name = 'Parent';
}

Parent.prototype.getName = function () {
    return this.name;
}

function Children () {
    Parent.call(this);
}

Children.prototype = Object.create(Parent.prototype);
Children.prototype.constructor = Children;
function Parent () {
    this.name = 'Parent';
}

Parent.prototype.getName = function () {
    return this.name;
}

function Children () {
    Parent.call(this);
}

Children.prototype = Object.create(Parent.prototype);
Children.prototype.constructor = Children;

Object.create 的实现原理如下:

js
const objectCreate = (parentPrototype) => {
    const noop = function () {};
    noop.prototype = parentPrototype;
    return new noop();
}
const objectCreate = (parentPrototype) => {
    const noop = function () {};
    noop.prototype = parentPrototype;
    return new noop();
}

extends 继承

优点:简洁美观

js
class Parent {
    constructor () {
        this.name = 'parent';
    }

    getName () {
        return this.name;
    }
}

class Children extends Parent {
    constructor () {
        super();
        this.topic = 'children';
    }
}

const children = new Children();
children.getName(); // parent
class Parent {
    constructor () {
        this.name = 'parent';
    }

    getName () {
        return this.name;
    }
}

class Children extends Parent {
    constructor () {
        super();
        this.topic = 'children';
    }
}

const children = new Children();
children.getName(); // parent