JavaScript中的物件導向----類

iDotNetSpace發表於2008-09-24

一、開篇

(以下文字一部分來自於整理的書籍內容,一部分則是總結自經驗)
     眾所周之,JavaScript是物件導向的語言。JavaScript的物件有三種:本地物件、內建物件、自定義類的物件。

其中本地物件和內建物件都是獨立於宿主由ECMAScript實現的。這裡所說的本地物件和內建物件實際上跟.Net中的類的概念相似。本地物件和內建物件的區別在於本地物件在使用時要例項化,而內建物件就像所謂的靜態類,可以直接使用。

JS中的本地物件有:Object Function Array String Boolean Number Date RegExp

Error等;內建物件有:Global和Math

下面著重介紹一下自定義類的五種方式:

二、在JavaScript中自定義類

1、工廠方法

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtfunction 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、建構函式方法

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtfunction 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、原型方式

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtfunction 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、建構函式/原型方式

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtfunction 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、動態原型方式

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtfunction 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。

例子如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtfunction 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.屬性

這樣的話顯得更物件導向了,但是建構函式方法的老毛病還是沒有改掉,物件的函式還是會被重複建立,但是我相信在一般情況下這對效能構不成威脅的。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-462841/,如需轉載,請註明出處,否則將追究法律責任。

相關文章