JavaScript中的面向对象----类

 

一、开篇

(以下文字一部分来自于整理的书籍内容,一部分则是总结自经验)
     众所周之,JavaScript是面向对象的语言。JavaScript的对象有三种:本地对象、内置对象、自定义类的对象。

其中本地对象和内置对象都是独立于宿主由ECMAScript实现的。这里所说的本地对象和内置对象实际上跟.Net中的类的概念相似。本地对象和内置对象的区别在于本地对象在使用时要实例化,而内置对象就像所谓的静态类,可以直接使用。

JS中的本地对象有:Object Function Array String Boolean Number Date RegExp

Error等;内置对象有:Global和Math

下面着重介绍一下自定义类的五种方式:

二、在JavaScript中自定义类

1、工厂方法

function createCar(){
    
var oTempCar = new Object();
    oTempCar.color 
= "red";
    oTempCar.doors 
= 4;
    oTempCar.mpg 
= 23;
    oTempCar.showColor 
= function(){
        alert(
this.color);
    }
    
return oTempCar;
}

var oCar1 = createCar();
oCar1.showColor();

缺点:缺点很多,基本上不会用到

2、构造函数方法

function Car(sColor,iDoors,iMpg){
    
this.color = sColor;
    
this.doors = iDoors;
    
this.mpg = iMpg;
    
this.showColor = function(){
        alert(
this.color);
    }
}

var oCar1 = new Car("red",4,23);
oCar1.showColor();
alert(oCar1 
instanceof Car);

 

原理:我们所谓的类还是js的一个Function而已,在Function前面用new运算符的时候,会自动创建一个object实例,并且类里面的this都指向这个object,在Function运行结束的时候,将this返回。所以其本质还是工厂方法。

优点:看起来和更像一个类 声明实例用new运算符

缺点:对象的函数会重复生成

3、原型方式

function Car(){
}
Car.prototype.color 
= "red";
Car.prototype.doors 
= 4;
Car.prototype.mpg 
= 23;
Car.prototype.showColor 
= function(){
    alert(
this.color);
}

var oCar1 = new Car();
oCar1.showColor();
alert(oCar1 
instanceof Car);

原理:js中的prototype

优点:避免了函数的重复创建

缺点:没有带参数的构造函数 属性如果是引用类型(比如Array),那么一个对象的属性改变,另外一个对象的同一个属性也会跟着改变

4、构造函数/原型方式

function Car(sColor,iDoors,iMpg){
    
this.color = sColor;
    
this.doors = iDoors;
    
this.mpg = iMpg;
}
Car.prototype.showColor 
= function(){
    alert(
this.color);
}

var oCar1 = new Car("red",4,23);
oCar1.showColor();
alert(oCar1 
instanceof Car);

 

优点:避免了函数的重复创建 并且避免了构造函数方法的引用类型属性的缺点

缺点:方法在类的外边定义的

5、动态原型方式

function Car(sColor,iDoors,iMpg){
    
this.color = sColor;
    
this.doors = iDoors;
    
this.mpg = iMpg;
    
if(typeof Car._initialized == "undefined"){
        Car.prototype.showColor 
= function(){
            alert(
this.color);
        }
        Car._initialized 
= true;
    }
}

var oCar1 = new Car("red",4,23);
oCar1.showColor();
alert(oCar1 
instanceof Car);

 

原理:Car也可以有属性的 通过_initialized这个标志确保方法只被声明一次

优点:避免了函数的重复创建 属性和方法都写在类的定义里

缺点:

三、我所使用的类

1、关于私有变量:

JavaScript中,基本上没法区分私有变量和公共变量,但是可以在命名上区分,一般习惯在私有变量的前后各加上两个下划线 this.__privatePropery__或者是在变量前加一个下划线this._privateProperty。

2、从构造函数方法衍生

对于第二种方法——构造函数方法对于私有变量的处理却有很大的优势!它可以将私有变量做到与外部隔离。这种隔离是将私有变量和方法在类里面用var来声明,而共有的变量和方法用赋值给this。

例子如下:

function Car(sColor,iDoors,iMpg){
    
var self = this;
    
this.color = sColor;
    
this.doors = iDoors;
    
var mpg = iMpg;//私有变量
    this.showCarInfo = function(){
        alert(
this.color);
        alert(mpg);
//不是this.mpg
    }
    
var privateShowCarInfo = function(){
        
//这时只能访问私有变量
        //alert(this.color);//会出错
        alert(mpg);//可以访问
        //那怎么才能访问this.color呢?总不可能私有方法不能访问公共属性吧?
        //在类里面设置一个私有变量,让他指向这个实例//第二行中var self = this;
        alert(self.color);//调用成功//当然 公共方法也能访问self
    }
    
this.anotherShowCarInfo = function(){
        privateShowCarInfo();
    }
}

var oCar1 = new Car("red",4,23);
oCar1.showCarInfo();
oCar1.anotherShowCarInfo();
alert(oCar1 
instanceof Car);

 

总之:this.方法能访问this.属性和var 变量

Var方法只能访问var变量,需要借助self变量来访问this.属性

这样的话显得更面向对象了,但是构造函数方法的老毛病还是没有改掉,对象的函数还是会被重复创建,但是我相信在一般情况下这对性能构不成威胁的。

 

posted @ 2009-08-04 14:22  ting_gt  阅读(245)  评论(0编辑  收藏  举报