JavaScript里继承的实现

真正的面向对象语言必须支持继承机制,即一个类能够重用(继承)另一个类的方法和属性,在上一篇文章里介绍了 javascript 里的类实现 ,这里介绍下继承的实现。
JavaScript里的继承机制并不是明确规定的,而是通过模仿实现的。
一:对象冒充(object masquerading)
对象冒充是如何在函数环境中使用this关键字后发展起来的,其原理如下:构造函数使用this关键字给所有的属性和方法赋值(采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可以使用ClassA的构造函数成为ClassB的方法,然后调用它。ClassB就会收到ClassA的构造函数中定义的属性和方法。

function ClassA(sColor)
{
    
this.color = sColor;
    
this.sayColor = function()
    
{
        alert(
this.color);
    }
;
}

function ClassB(sColor)
{
    
this.newMethord= ClassA;
    
this.newMethod(sColor);
    
delete this.newMethod;
}
上面的代码中ClassA赋予了方法newMethod(函数只是指向它的指针)。然后调用了该方法,传递给它的是ClassB的构造函数的参数sColor。最后的代码删除了对ClassA的引用,这样以后就不能再调用它了,所有的新属性和新方法都必须在删除了新方法的代码行后定义,否在会覆盖超类的相关属性和方法:
function ClassB(sColor,sName)
{
    
this.newMethor = ClassA;
    
this.newMethor(sColor);
    
delete this.newMethor;
    
    
this.name = sName;
    
this.sayName = function()
    
{
        alert(
this.name);
    }
;
}
二:call()方法
call()方法是与经典的对象冒充方法最相似的方法,它的第一个参数用作this的对象,其它参数都直接传递给函数自身,如:
function sayColor(sPrefix,sSuffix)
{
    alert(sPrefix 
+ this.color + sSuffix);
}

var obj = new object();
obj.color 
= "red";
sayColor.call(obj,
"The color is ",", a very nice color indeed.");
//outputs "The color is red, a very nice color indeed."
  在上面的例子里,函数sayColor()在对象外定义,即使它不属于任何对象,也可以引用关键字this,对象obj的color属性等于"red",调用call()方法时对一个参数是obj,说明应赋予sayColor()函数中的this关键字是obj,要与继承机制的对象冒充方法一起使用该方法,只需将前三行的赋值,调用和删除代码替换:
function ClassB(sColor,sName)
{
//    this.newMethor = ClassA;
//
    this.newMethor(sColor);
//
    delete this.newMethor;
    ClassA.call(this,sColor);
    
    
this.name = sName;
    
this.sayName = function()
    
{
        alert(
this.name);
    }
;
}

三:apply()方法
apply()方法有二个参数,用作this的对象和要传递给函数的参数数组,列如:
function sayColor(sPrefix,sSuffix)
{
    alert(sPrefix 
+ this.color + sSuffix);
}

var obj = new object();
obj.color 
= "red";
sayColor.apply(obj,
new Array("The color is ",", a very nice color indeed."));
//outputs "The color is red, a very nice color indeed."
四:原型链
prototype对象是个模板,要实例化的对象都以这个模板为基础,prototype对象的任何属性和方法都被传递给那个类的所有实例,原型链用这种功能实现继承机制:
function ClassA()
{
}


ClassA.prototype.color 
= "red";
ClassA.prototype.sayColor 
= function()
{
    alert(
this.color);
}
;

function ClassB()
{
}

ClassB.prototype 
= new ClassA();
ClassB.prototype = new ClassA(); 这句把ClassB的prototype属性设置为ClassA的实例,与对象冒充相似,子类的所有属性和方法都必须出现在prototype属性被赋值后,因为在它之前所有的方法都会被删除,因为prototype属性被替换成了新的对象,添加了新的原始对象将被销毁,所以,为ClassB类添加name属性和sayName()方法的代码如下:
function ClassB()
{
}


ClassB.prototype 
= new ClassA();

ClassB.prototype.name 
= "";
ClassB.prototype.sayName 
= function()
{
    alert(
this.name);
}
;
五:混合方式
这种方式使用构造函数定义类,并未使用任何原型。重写前面的例子,代码如下:
function ClassA(sColor)
{
    
this.color = sColor;
}

ClassA.prototype.sayColor 
= function()
{
    alert(
this.color);
}
;
function ClassB(sColor,sName)
{
    ClassA.call(
this,sColor);
    
this.name = sName;
}

ClassB.prototype 
= new ClassA();
ClassB.prototype.sayName 
= function()
{
    alert(
this.name);
}
 
 
posted @ 2008-06-17 12:10  my favorite  阅读(219)  评论(0编辑  收藏  举报