接上篇:面向对象的程序设计(上)
三、继承
JavaScript主要通过原型链实现继承。
1.原型链
原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的。这样,子类型就能够访问超类型的所有属性和方法。
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.prototype;
};
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
下图展示了以上构造函数和原型之间的关系。
注意:读取模式访问实例属性时的搜索顺序:1)搜索实例;2)搜索子类型原型;3)搜索超类型原型;
确定原型和实例的关系
- instanceof操作符
- isPrototypeOf()方法
- 对象实例共享所有继承的属性和方法;
- 不能向超类型的构造函数中传递参数;
2.借用构造函数
以上问题可通过借用构造函数来解决,即在子类型构造函数的内部调用超类型构造函数。
function SuperType(name){
this.name = name;
}
function SubType(){
//继承了SuperType,同时还传递了参数
SuperType.call(this, "Nicholas");
//实例属性
this.age = 29;
}
var instance = new SubType();
alert(instance.name); //"Nicholas"
alert(instance.age); //29
3.组合继承
使用最多的继承模式是组合继承,即使用原型链继承共享的属性和方法,而通过借用构造函数继承实例属性。
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;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SuberType;
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(instance1.colors); //"red,blue,green"
instance1.sayName(); //"Greg"
instance1.sayAge(); //27
4.原型式继承
可以在不必预先定义构造函数的情况下实现继承,本质是执行给定对象的浅复制,而复制得到的副本还可以进一步改造。
function object(o){
function F(){}
F.prototype = o;
return new F();
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var antherPerson = object(person);
//var antherPerson = object.creat(person); //ES5新增的方法规范原型式继承
antherPerson.name = "Greg";
antherPerson.friends.push("Rob");
alert(person.friends); //"Shelby, Court, Van,Rob"
5.寄生式继承
与原型式继承非常相似,也是基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象。为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题,可以将这个模式与组合模式一起使用。
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);
};