无梦空间

JavaScript极限编程

导航

3)类的实现

    1)理解类的实现机制
    在JavaScript中可以用function关键字来定义一个"类",并为类添加成员.在函数内部通过this指针引用的常量或者方法都会成为类的成员,例如:
function class1(){
      
var s="abc";
      
this.p1=s;
      
this.method1=function(){
             alert(
"this is a test method");
      }
}
var obj1=new class1();
    通过new class1()获得对象obj1,对象obj1便自动获得了属性p1和方法method1.
    在
JavaScript中,function本身的定义就是类的构造函数,下面介绍使用new创建对象的流程:
1>当解释器遇到new操作符时,便创建一个空对象.
2>开始运行class1这个函数,并将其中的this指针都指向这个新建的对象;
3>因为当给对象不存在的属性赋值时,解释器就会为对象创建该属性,这样函数执行就是初始化
并扩展这个对象的过程.(创建对象的过程,本质上还是对对象的属性(方法)扩展的过程!)
4>当函数执行完后,new操作符就返回初始化后的对象.

    通过这整个过程,
JavaScript就实现了面向对象的基本机制.
    可见,在
JavaScript中,function的定义实际上就是实现一个对象的构造器,是通过函数来完成的,这种方式的缺点是:
1>将所有的初始化语句\成员定义放在一起,代码逻辑不够清晰,不易实现复杂的功能.
2>每创建一个类的实例,都要执行一次构造函数.构造函数中定义的属性和方法总被重复的创建,例如:
this.method1 = function(){
    alert(
"this is a test method");
}
    这里的method1每创建一个class1的实例,都会被创建一次,造成了内存的浪费.下一节介绍另一种类定义的机制:prototype对象,可以解决构造函数中定义类成员带来的缺点.

    2)使用prototype原型对象来定义类成员.
    当new一个function时,该函数对象的成员将自动赋给所创建的对象.例如:
   
<script language="JavaScript" type="text/javascript">
//定义一个只有一个属性prop的类
function class1(){
      
this.prop=1;
}
//使用函数的prototype属性给类定义新成员
class1.prototype.showProp=function(){
      alert(
this.prop);
}
//创建class1的一个实例
var obj1=new class1();
//调用通过prototype原型对象定义的showProp方法
obj1.showProp();
</script>
   prototype是一个JavaScript对象,可以为prototype对象添加\修改\删除方法和属性,从而为一个类添加成员定义.
    了解了函数的prototype对象,现在来看new的执行过程:
1>创建一个新的对象,并让this指针指向它.
(隐式的)
2>将函数的prototype对象的所有成员都赋给这个新对象.(隐式的)
3>执行函数体,对这个对象进行初始化操作.
4>返回1>中创建的对象.
(隐式的)

    和上一节的new相比,多了用prototype来初始化对象的过程.这个初始化过程发生了函数体(构造器)执行之前,所以可以在函数体内部调用prototype中定义的属性和方法,例如:
<script language="JavaScript" type="text/javascript">
//定义一个只有一个属性prop的类
function class1(){
        
//由于class1的prototype现在已经被赋给了this指向的对象,因此可以调用showProp方法了.
      this.prop=1;
      
this.showProp();
}
//使用函数的prototype属性给类定义新成员
class1.prototype.showProp=function(){
      alert(
this.prop);
}
//创建class1的一个实例
var obj1=new class1();
</script>
    这里在class1的内部成功调用了class1.prototype中定义发方法showProp,说明
class1.prototype是最优先赋给this指向的对象的.
    prototype对象专用于设计类的成员,它是和一个类紧密相关的.此外,prototype还有一个重要的属性:constructor,表示对该构造函数的引用,例如:
function class1(){
      alert(
1);
}
class1.prototype.constructor(); 
//调用类的构造函数
    这段代码运行后将会弹出显示"1"的对话框,可以看出prototype是和类的定义紧密相关的,事实上:class1.prototype.constructor等价于class1,即可用来进行实例化对象.

    3)一种JavaScript类的设计模式
   
前面已经介绍了如何定义一个类,如何初始化一个类的实例,且类可以在function定义的函数体中添加成员,又可以用prototype定义类的成员,编程的代码显得混乱。如何以一种清晰的方式来定义类呢?下面给出了一种类的实现模式。
    在
JavaScript 中,由于对象灵活的性质,在构造函数中也可以为类添加成员,在增加灵活性的同时,也增加了代码的复杂度.为了提高代码的可读性和开发效率,可以采用这种定 义成员的方式,使用prototype对象来替代,这样function的定义就是类的构造函数,符合传统意义类的实现:类名和构造函数是相同的.例如:
function class1(){
    
//构造函数
}
//通过指定prototype对象来实现类的成员定义
class1.prototype = {
    someProperty:
"sample",  //属性
    someMethod:function(){
        
//方法代码
    }
    
//
}
    上面的代码用一种很清晰的方式定义了class1,构造函数直接用类名来实现,而成员使用无类型对象来定义,以列表的方式实现了所有属性和方法,并且可以在定义的同时初始化属性的值.



posted on 2006-08-16 07:47  想那风霜雪  阅读(298)  评论(1编辑  收藏  举报