温故知新之继承的几种方式

118 阅读1分钟
/**
 * 原型链继承
 *
 * 问题:
 * 1.包含引用类型值,所有实例会共享相同属性
 * 2.在不影响所有对象实例的前提下,没办法向超类型的构造函数传递参数
* */
function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function () {
    return this.property;
};

function SubType() {
    this.subproperty = false;
}

SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function () {
    return this.subproperty;
};

/**
 * 借用构造函数继承
 *
 * 问题:
 * 1. 方法都在父类型的构造函数中定义,无法实现复用。且父类型中
 *    定义的方法,子类型是无法访问的
 * */

function SuperType() {
    this.arr = ['a', 'b']
}

function SubType() {
    SubType.call(this);
}

/**
 * 原型式继承
 *
 * 问题:
 * 1. ES6 api Object.create具有同等功能,再用此模式显得多余
 * 2. 原型对象中包含引用类型时,所有基于该原型对象的实例会共享相同属性
 * */

function object(o) {
    function F() {

    }
    F.prototype = o;
    return o;
}

/**
 * 寄生式继承
 *
 * 1. 仅仅是通过一个函数来给对象添加方法,没有类型区分
 * 2. 函数内部定义的函数也无法复用
 * */
function createObject(originalProto) {
    const clone = JSON.parse(JSON.stringify(originalProto)); //简单粗暴的clone

    clone.foo = function () {

    };

    return clone;
}

/**
 * 寄生组合继承
 * */
function inheritPrototype(subType, superType) {
    const protoType = JSON.parse(JSON.stringify(subType.prototype));
    protoType.constructor = subType;
    subType.prototype = protoType;
}

function SuperType() {
    this.property = true;
    this.arr = ['a', 'b'];
}

SubType.prototype.foo = function () {

};

function SubType() {
    SubType.call(this);
    this.subproperty = 'foo';
}

inheritPrototype(SubType, SuperType);

SubType.prototype.bar = function () {

};