Javascript 寄生组合式继承

接触了好几种继承模式了,在前一篇文章,我们就说到了一些继承方法,本以为组合是最好的,结果没想到还有。

故事从原型式继承说起:

function object(o) {
    function F(){}
    F.prototype = o;
    return new F();
}

var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};

var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

console.log(person.friends);

原型式继承似乎略像prototype的情况,输出为[ 'Shelby', 'Court', 'Van', 'Rob', 'Barbie' ]

之后我们可以用自带的Object.create()来代替定义的函数。

寄生式继承也是运用了这一特点

function createAnother(original) {
    var clone = Object.create(original);
    clone.sayHi = function() {
        console.log("hi");
    };
    return clone;
}

var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};

var anotherPerson = createAnother(person);
anotherPerson.sayHi();

不懂的是为什么在这里定义的sayHi就无法共享给person。

而寄生组合式继承目前似乎被称为最高效的方式(-_-其实我也没明白)

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

function SuperType(name) {
    this.name = name;
    this.color = ["red", "blue", "green"];
}

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);
};

植入部分

如果您觉得文章不错,可以通过赞助支持我。

如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。

标签: 知识, 语法, 存疑

已有 2 条评论

  1. Horizon

    我感觉js里要继承核心还是prototype, 也就是原型链继承,或者在部分平台下直接操作__proto__可以简化一些
    之前那篇Javascript call()与apply()里的继承方式有点问题,SubType.prototype = new SuperType();直接调用了父类的构造函数,这样会导致原先的实例变量变为类变量,这篇文章中用的方法才是通常js里的继承

    1. Horizon

      一般来说,prototype里都是方法,而别的类型的属性(Object,Array,String,Number,RegExp等)通常在构造函数中初始化。
      虽然我好像没有见过不是这样做的js oop,但是还是感觉不够好。
      可能是js的oop确实比较弱,有些问题比如,怎么实现类变量,要显式的调用父类构造函数,调用被覆盖的父类方法要显式的写出父类名(例如SUPERCLASSNAME.prototype.FUN.call(this)),这点有点类似c++, 还有就是封装性不足。

添加新评论