1、原型链实现继承

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

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

//继承了SuperType
SubType.prototype = new SuperType();

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

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

2、借用构造函数

原型链的问题是对象实例共享所有继承的属性和方法,因此不适宜单独使用。解决这个问题的技术是借用构造函数,即在子类型构造函数的内部调用超类型构造函数。这样就可以做到每个实例都具有自己的属性,同时还能保证只使用构造函数模式来定义类型。

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

function SubType(){
    //继承了SuperType,
    SuperType.call(this);//在子类型构造函数的内部调用超类型构造函数
}

var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors);   //"red,blue,green,black"

var instance2 = new SuperType();
alert(instance2.colors);   //"red,blue,green"

3、组合继承

思想:在子类型构造函数的内部调用超类型构造函数。使用最多的继承模式是组合继承,这种模式使用原型链继承共享的属性和方法,而借用构造函数继承实例属性。

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

SuperType.prototype.sayName = function() {
    alert(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() {
    alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors);   //"red,blue,green,black"
instance1.sayName();  //"Nicholas"
instance1.sayAge();  //29

var instance2 = new SubType("Greg" ,27);
alert(instance2.colors);  //"red,blue,green"
instance2.sayName();  //"Greg"
instance2.sayAge();  //27

4、原型式继承

(1)借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型
(2)在object()函数内部,先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。
(3)原型式继承,可以在不必预先定义构造函数的情况下实现继承,其本质是执行给定对象的浅复制。而复制的副本还可以得到进一步的改造。

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

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

var yetAbotherPerson = object(perosn);
yetAbotherPerson.name = "Linda";
yetAbotherPerson.firends.push("Barbie");

alert(person.friends);  //"Shelby, Court, Van, Greg, Linda"

5、寄生式继承

与原型式继承非常相似,也是基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象。为了解决组合继承模式由于多次调用超类型函数而导致的低效率问题,可以将这个模式与组合继承一起使用。

function creatAnother(original) {
    var clone = object(original);   //通过调用函数创建一个新对象
    clone.sayHi = function() {      //以某种方式来增强这个对象
        alert("hi");
    };
    return clone;  //返回这个对象
}
var person = {
   name : "Nicholas",
   friends : ["Shelby", "Court", "Van"]
};

var anotherPerson = creatAnother(person);
anotherPerson.sayHi();  //"hi"

6、寄生组合式继承

(1)集寄生式继承与组合继承的优点于一身,是实现基于类型继承的最有效的方式。可以解决组合继承调用两次构造函数导致子类最终会包含超类对象的全部实例属性的问题。
(2)寄生式组合继承,就是通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其思想是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需的无非就是超类型原型的一个副本而已。本质上就是,使用寄生式继承来继承超类型的原型,然再将结果指定给子类型的原型。其基本模式如下:

function inheritPrototype(SubType,superType) {
    var prototype = object(superType.prototype);   //创建对象
    prototype.constructor = subType;               //增强对象
    subType.prototype = prototype;                 //指定对象
}

这个函数接收两个参数:子类型构造函数和超类型构造函数。
第一步是创建超类型原型的一个副本;
第二步是为创建的副本添加constructor属性,从而弥补因重写原型而失去的默认的constructor属性;
第三步将新创建的对象(即副本)赋值给子类型的原型。

function inheritPrototype(SubType,superType) {
    var prototype = object(superType.prototype);   //创建对象
    prototype.constructor = subType;               //增强对象
    subType.prototype = prototype;                 //指定对象
}

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

SuperType.prototype.sayName = function() {
    alert(this.name);
};
function SubType(name ,age) {
    //继承属性
    SuperType.call(this.name);      
    this.age = age;
}

inheritPrototype(SubType, SuperType);

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

皮卡丘丘丘
50 声望12 粉丝

不忘初心方得始终,念念不忘必有回响