JavaScript 高级程序设计 继承
1. 对象冒充
function ClassA(sColor) { this.color=sColor; this.sayColor=function (){ alert(this.color); } } function ClassB(sColor,sName) { this.newMethod=ClassA;?? ?函数名只是指向它的指针 this.newMethod=ClassA(sColor);? delete this.newMethod; this.name=sName; this.sayName=function (){ alert(this.name); } } var objA=new ClassA("red"); var objB=new ClassB("blue","Joe"); objA.sayColor(); objB.sayColor(); objB.sayName();
?
弊端: 对象冒充可以支持多重继承,但可能两个父类具有同名的属性或方法。
?
2. call方法
?
function sayColor(sPrefix,sSuffix)
?? ? ? ? ? ? ? {
?? ? ? ? ? ? ? ? ? ?alert(sPrefix+this.color+sSuffix);
?? ? ? ? ? ? ? }
?? ? ? ? ? ? ? var obj=new Object();
?? ? ? ? ? ? ? obj.color="red";
?? ? ? ? ? ? ? sayColor.call(obj,"The color is "," ,very good!");
与对象冒充方法最相似,它的第一个参数用作this的对象,其他参数直接传递给函数本身。
第一个参数obj,说明应该赋予sayColor函数中的this关键字值是obj
?
要与继承机制的对象冒充方法一起使用该方法,代码如下:
?
function ClassA(sColor)
?? ? ? ? ? ? ? ?{
?? ? ? ? ? ? ? ? ? ?this.color=sColor;
?? ? ? ? ? ? ? ? ? ?this.sayColor=function (){
?? ? ? ? ? ? ? ? ? ? ? ?alert(this.color); ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ?function ClassB(sColor,sName)
?? ? ? ? ? ? ? ?{ ? ? ? ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ? ? ?ClassA.call(this,sColor);
?? ? ? ? ? ? ? ? ? ?this.name=sName;
?? ? ? ? ? ? ? ? ? ?this.sayName=function (){
?? ? ? ? ? ? ? ? ? ? ? ?alert(this.name); ? ? ? ? ? ??
?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ?}
?
3. apply()方法 ?有两个参数,用作this的对象和要传递给函数的参数的数组。
?
?? ?function onLoad()
?? ? ? ? ? ?{
?? ? ? ? ? ? ? function sayColor(sPrefix,sSuffix)
?? ? ? ? ? ? ? {
?? ? ? ? ? ? ? ? ? ?alert(sPrefix+this.color+sSuffix);
?? ? ? ? ? ? ? }
?
?? ? ? ? ? ? ? var obj=new Object();
?? ? ? ? ? ? ? obj.color="red";
?? ? ? ? ? ? ? sayColor.apply(obj,new Array("The color is "," ,very good!"));
?? ? ? ? ? ?} ? ??
?
?
function ClassA(sColor)
?? ? ? ? ? ? ? ?{
?? ? ? ? ? ? ? ? ? ?this.color=sColor;
?? ? ? ? ? ? ? ? ? ?this.sayColor=function (){
?? ? ? ? ? ? ? ? ? ? ? ?alert(this.color); ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ?function ClassB(sColor,sName)
?? ? ? ? ? ? ? ?{ ? ? ? ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ? ? ?ClassA.apply(this,new Array(sColor));
?? ? ? ? ? ? ? ? ? ?this.name=sName;
?? ? ? ? ? ? ? ? ? ?this.sayName=function (){
?? ? ? ? ? ? ? ? ? ? ? ?alert(this.name); ? ? ? ? ? ??
?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ?}
?
4. 原型链
?? ?prototype对象是个模板,要实例化的对象都以这个模板为基础。prototype对象的任何属性和方法都被传递给那个类的所有实例。
?? ?function ClassA(){ } ClassA.prototype.color="red"; ClassA.prototype.sayColor=function (){ alert(this.color); } function ClassB(){ } ClassB.prototype=new ClassA();?? ?
把ClassB的prototype属性设置成ClassA的实例。可以得到ClassA的所有属性和方法,又不用逐个将他们赋予ClassB的prototype属性。子类的所有属性和方法必须在prototype属性被赋值后,因为在它之前赋值的所有方法都会被删除。因为prototype属性被替换成新对象,添加了新方法的原始对象将被销毁。
?
?
?? ? ?function ClassA(){ ? ? ? ? ? ? ?
?
?? ? ? ? ? ? ?}
?? ? ? ? ? ? ?ClassA.prototype.color="red";
?? ? ? ? ? ? ?ClassA.prototype.sayColor=function (){
?? ? ? ? ? ? ? ?alert(this.color); ? ? ? ? ? ? ? ? ? ? ? ? ?
?? ? ? ? ? ? ?}
?? ? ? ? ? ? ?function ClassB(){ ? ? ? ? ? ? ?
?
?? ? ? ? ? ? ?}
?? ? ? ? ? ? ?ClassB.prototype=new ClassA();
?? ? ? ? ? ? ?ClassB.prototype.name="";
?? ? ? ? ? ? ?ClassB.prototype.sayName=function (){
?? ? ? ? ? ? ? ?alert(this.name); ? ? ? ? ? ? ? ? ? ? ? ??
?? ? ? ? ? ? ?}
?
?? ? ? ? ? ? ?var objA=new ClassA();
?? ? ? ? ? ? ?var objB=new ClassB();
?? ? ? ? ? ? ?objA.color="red";
?? ? ? ? ? ? ?objB.color="blue";
?? ? ? ? ? ? ?objB.name="Joe";
?
?? ? ? ? ? ? ?objA.sayColor();
?? ? ? ? ? ? ?objB.sayColor();
?? ? ? ? ? ? ?objB.sayName();
?弊端:不支持多重继承,原型链会用另一个类型的对象重写类的prototype属性。
?
5. 混合方式:用对象冒充继承构造函数的属性,用原型链继承prototype对象的方法。
?? ??function ClassA(sColor){ ?
?? ? ? ? ? ? ? ?this.color=sColor; ? ? ??
?? ? ? ? ? ? ?}
?
?? ? ? ? ? ? ?ClassA.prototype.sayColor=function (){
?? ? ? ? ? ? ? ?alert(this.color); ? ? ? ? ? ? ? ? ? ? ? ? ?
?? ? ? ? ? ? ?}
?? ? ? ? ? ? ?function ClassB(sColor,sName){ ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ?this.color=sColor;
?? ? ? ? ? ? ? ?this.name=sName; ? ? ? ?
?? ? ? ? ? ? ?}
?? ? ? ? ? ? ?ClassB.prototype=new ClassA(); ? ? ? ? ? ??
?? ? ? ? ? ? ?ClassB.prototype.sayName=function (){
?? ? ? ? ? ? ? ?alert(this.name); ? ? ? ? ? ? ? ? ? ? ? ??
?? ? ? ? ? ? ?}
?
?? ? ? ? ? ? ?var objA=new ClassA("red");
?? ? ? ? ? ? ?var objB=new ClassB("blue","Joe"); ? ? ? ? ? ?
?
?? ? ? ? ? ? ?objA.sayColor();
?? ? ? ? ? ? ?objB.sayColor();
?? ? ? ? ? ? ?objB.sayName();
?