Skip to content

Inheritance #2

@littlee

Description

@littlee
/*
    原型链继承
    给原型添加方法的代码一定要放在替换原型的语句之后
    不能使用对象字面量创建原型方法
    通过原型来实现继承,原型实际上会变成另一个类型的实例
    于是,原来的实例属性也变成了现在的原型属性
    创建子类型的实例时,不能向超类型的构造函数传递参数,
    实际上应该说是没有办法在不影响所有对象的实例的情况下,给超类型的构造函数传递参数
*/
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;
};

var instance = new SubType();
console.log(instance.getSuperValue()); // true;

/*
    借用构造函数(伪造对象,经典继承)
    方法都在构造函数中定义,代码无法复用
    在超类型的原型中定义的方法,对子类型而言是不可见的

*/
function SuperType(name) {
    this.name = name;
    this.colors = ['red', 'green', 'blue'];
}

function SubType() {
    SuperType.call(this, 'My Name');

    // 实例属性
    this.age = 22;
}

var instance1 = new SubType();
instance1.colors.push('black'); // red, green, blue, black
console.log(instance1.colors);

var instance2 = new SubType();
console.log(instance2.colors); // red, green, blue

/*
    组合继承(伪经典继承)
    最常用的继承方式,避免了原型链和借用构造函数的缺陷
    不足:会调用两次超类型的构造函数
*/
function SuperType(name) {
    this.name = name;
    this.colors = ['red', 'green', 'blue'];
}

SuperType.prototype.sayName = function() {
    console.log(this.name);
};

function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}

SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
    console.log(this.age);
}

var i1 = new SubType('Lee1', 22);
i1.colors.push('black');
console.log(i1.colors);
i1.sayAge();
i1.sayName();

var i2 = new SubType('Lee2', 33);
console.log(i2.colors);
i2.sayAge();
i2.sayName();

/*
    原型式继承
    ES5 的 Object.create 方法规范化了这个方式
*/
function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

/*
    寄生式继承
    object 函数不是必须的,任何可以返回对象的函数都可以用于此模式
*/
function createAnother(original) {
    var clone = object(original);
    clone.sayHi = function() {
        console.log('HI');
    };
    return clone;
}

/*
    寄生组合式继承

*/
function inheritPrototype(subType, superType) {
    var prototype = Object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}

function SuperType(name) {
    this.name = name;
    this.colors = ['red'];
}

SuperType.prototype.sayName = function() {
    console.log(this.name);
};

function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}

inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function() {
    console.log(this.age);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions