posts - 297,  comments - 1618,  trackbacks - 0
 

说明:本文为《JavaScript高级程序设计》第4章学习笔记。

一.             继承机制实例

几何形状只有两种,即椭圆形和多变形。圆是椭圆形的一种,它只有一个焦点。三角形、矩形和五边形都是多边形的一种,具有不同数量的边。正方形是矩形的一种,所有的边等长。这就构成了继承关系。

形状是椭圆形和多边形的基类。圆形继承了椭圆形,因此圆形是椭圆形的子类,椭圆形是圆形的超类

二.             继承机制的实现

要用ECMAScript实现继承机制,首先从基类入手。所有开发者定义的类都可以作为基类。出于安全原因,本地类和宿主类不能作为基类,这样可以防止编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击。

选定基类后,就可以创建它的子类了。是否使用基类完全由你决定。有时,你可能想创建不能直接使用的基类,它只是用户给予类公共通用的函数。在这种情况下,基类被看作抽象类

1.继承的方式

JavaScript中的继承机制并不是明确规定的,而是通过模仿实现的。开发者可以自己决定最适用的继承方式。

1)对象冒充

原理:构造函数使用this关键字给所有属性和方法赋值。因为构造函数只是一个函数,所以可使ClassA的构造函数成为ClassB的方法,然后调用它。ClassB就会收到ClassA的构造函数定义的属性方法。

Eg. 

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

}


function ClassB(sColor, sName) {
         
this.newMethod = ClassA;
         
this.newMethod(sColor);
         
delete this.newMethod;
         
this.name = sName;
         
this.sayName = function() {
       alert(
this.name);
}
     
}


2)call()方法

call()方法是与经典的对象冒充方法最相似的方法。它的第一个参数用作this的对象,其他参数都直接传递给函数本身。

Eg. 可将上例中的ClassB改成如下后,可达到先前同样的效果: 

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

}

 

3)apply()方法

该方法有两个参数,用作this的对象要传递给的参数的数组。

Eg.

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."));

可将上述的ClassB修改为如下这样:

function ClassB(sColor, sName) {
       ClassA.apply(
thisnew Array(sColor));
       
this.name = sName;
       
this.sayName = function() {
       alert(
this.name);
}
;
}

 

4)原型链

Prototype对象是个模板,要实例化的对象都以这个模板为基础。总而言之,prototype对象的任何属性和方法都被传递给那个类的所有实例。原型链利用这种功能来实现继承机制。

Eg.

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);
}
;

原型链的弊端是不支持多重继承。记住,原型链会用另一类型的对象重写类的prototype属性。

5)混合模式

对象冒充的主要问题是必须使用构造函数的方式,这不是最好的选择。不过如果使用原型链,就无需使用构造函数了。如果将这两种方式混合起来,将会达到更好的效果。

Eg.

 fuction 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 
= function() {
    alert(
this.name);
}
;

  调用代码如下所示:

var objA = new ClassA("red");
var objB = new ClassB("blue""AmigoXie");
objA.sayColor();
objB.sayColor();
objB.sayName();

 

2.一个更实际的例子

下面讲一个PolygonTriangleRectangle的例子。

1)创建基类Polygon

Eg. 

 function Polygon(iSides) {
         
this.sides = iSides;
}


Polygon.prototype.getArea 
= function() {
        
return 0;
}
;


 

2)创建子类

三角形Triangle的内容如下:

function Triangle(iBase, iHeight) {
        Polygon.call(
this3);
        
this.base = iBase;
        
this.height = iHeight;
}


Triangle.prototype 
= new Polygon();
Triangle.prototype.getArea 
= function() {
        
return 0.5 * this.base * this.height;
}
;

Rectangle的ECMAScript代码如下:

function Rectangle(iLength; iWidth) {
        Polygon.call(
this4);
        
this.length = iLength;
        
this.width = iWidth;
}


Rectangle.prototype 
= new Polygon();
Rectangle.prototype 
= function() {
        
return this.length * this.width;
}
;

 

3)测试代码 

var triangle = new Triangle(124);
var rectangle = new Rectangle(2210);
alert(triangle.sides);
alert(triangle.getArea());
alert(rectangle.sides);
alert(rectangle.getArea());

 

4)采用动态原型方法如何?

function Polygon(iSides) {
        
this.sides = iSides;
        
if (typeof Polygon._initialized == "undefined"{
       Polygon.prototype.getArea 
= function() {
       
return 0;
}
;

Polygon._initialized 
= true;
}

}


function Triangle(iBase, iHeight) {
        Polygon.call(
this3);
        
this.base = iBase;
        
this.height = iHeight;
        
if (typeof Triangle._initialized == "undefined"{
       Triangle.prototype 
= new Polygon();
       Triangle.prototype.getArea 
= function() {
       
return 0.5 * this.base * this.height;
}
;

Triangle. _initialized 
= true;
}

}


Triangle.prototype 
= new Polygon();

 

三.             小结

本章介绍了ECMAScript中用对象冒充和原型链实现的继承概念。学会结合使用这些方式才是建立类之间的继承机制的最好方式。

posted on 2007-09-04 08:59 阿蜜果 阅读(935) 评论(3)  编辑  收藏 所属分类: Javascript


FeedBack:
# re: JavaScript学习笔记——继承
2007-09-04 13:48 | freeman
好东西! 我先顶一下,不知道有没有数据库设计的东东,小弟正在学那个。  回复  更多评论
  
# re: JavaScript学习笔记——继承
2007-09-04 15:54 | mortal
姐姐,有点问题请教下,
<object>
<param name="enableContextMenu" value="0">
<param name="fullScreen" value="0">
</object>
假如我要取得enableContextMenu的值,请问怎么用js取得?  回复  更多评论
  
# re: JavaScript学习笔记——继承
2007-09-10 11:32 | 冬虎
小丫头,不错,只是照片有点糊,看不清脸,能不能换张清晰点的吼吼,  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2007年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

      生活将我们磨圆,是为了让我们滚得更远——“圆”来如此。
      我的作品:
      玩转Axure RP  (2015年12月出版)
      

      Power Designer系统分析与建模实战  (2015年7月出版)
      
     Struts2+Hibernate3+Spring2   (2010年5月出版)
     

留言簿(262)

随笔分类

随笔档案

文章分类

相册

关注blog

积分与排名

  • 积分 - 2284416
  • 排名 - 3

最新评论

阅读排行榜

评论排行榜