面向对象设计——继承

序:回顾构造函数、原型和实例之间的关系

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

1.原型链

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

function Sub(){
    this.subproperty = false;
}
Sub.prototype = new Super();  //给原型添加方法的代码一定要放在替换原型的语句之后
//添加新方法
Sub.prototype.getSubValue = function(){
    return this.subproperty;
};
//重写超类型的方法
Sub.prototype.getSuperValue = function(){
    return false;
}
var instance = new Sub();
alert(instance.getSuperValue());  //false 

缺点:

(1)引用类型的原型实例会被所有实例共享。

(2)子类不能向超类传递参数。

2.借用构造函数

function Super(name){
    this.name = name;
}
function Sub(){
    //继承了Super,同时还传递了参数
    Super.call(this, "Nicholas");
    //实例属性
    this.age = 29;
}
var instance = new Sub();
alert(instance.name);  //"Nicholas"
alert(instance.age);   //29

缺点:无法避免构造函数存在的问题——方法都在构造中定义,因此函数复用就无从谈起了。

3.组合继承(常用)

将原型链和借用构造函数组合到一块

function Super(name){
    this.name = name;
    this.colors = ["red","blue","green"];
}
Super.propotype.sayName = function(){
    alert(this.name);
};
function Sub(name,age){
    //继承属性
    Super.call(this, name);   //第二次调用Super
    this.age = age;
}
//继承方法
Sub.prototype = new Super();  //第一次调用Super
Sub.prototype.constructor = Sub;
Sub.propotype.sayAge = function(){
    alert(this.age);
};

var instance1 = new Sub("Nicholas",29);
instance1.colors.push("black");

缺点:会两次调用父类型的构造函数。

4.原型式继承

必须有一个对象作为另一个对象的基础。

ECM5通过新增Object.create()方法规范了原型式继承。这个方法接收两个参数:一个用作新对象原型的对象和(可选的)一个为新对象定义额外属性的对象。

function object(o){
    function F(){}
    F.prototype = o;
    return new F();
}
var person = {
    name: "Nicholas",
    friends: ["Shelby","Court","Van"]
};
var anotherPerson = object(person);
anotherPerson.friends.push("Rob");
alert(person.friends);  //"Shelby,Court,Van,Rob"

优势:不想兴师动众的创建构造函数,只想一个对象与另一个对象保持相似的情况下,原型式可以完全胜任。

缺点:属性共享。

5.寄生式继承

function createAnother(original){
    var clone = object(original);  //object()函数不是必须的,任何返回新对象的函数都可以
    clone.sayHi = function(){
        alert("hi");
    };
    return clone;
}
var person = {
    name: "Nicholas",
    friends:["Shelby","Court","Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();  //"hi"

6.寄生组合式继承(最理想的继承范式)

原理:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非是一个超类型原型的副本。

function inheritPrototype(subType, superType){
    var prototype = object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
function SuperType(name) {
    this.name = name;
    this.colors = ["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);
}

 

posted @ 2016-07-26 17:33  简惬  阅读(329)  评论(0编辑  收藏  举报