JavaScript物件導向的特性

來源:互聯網
上載者:User
如果你使用JavaScript編程,你或許會懷疑它是否包含了物件導向(OO)的結構。實際上,JavaScript的確支援物件導向的架構――在某種程度上。本文將通過一個可擴充向量圖形(SVG)的執行個體來說明JavaScript的OO結構。

 

我如何在類中定義方法和屬性?

 

OO開發的一個基本方面是類及其相應的方法和/或屬性的使用。JavaScript通過function關鍵字支援類(及其屬性)的使用。下面的代碼定義了一個叫做Figure的JavaScript類:
function Figure() {
this.centerX=0;
this.centerY=0;
this.area=0;
this.transform = transform; // methods are defined like this
function transform(moveX,moveY,angle) {
this.centerX += moveX;
this.centerY += moveY;
} }

這個Figure類有三個屬性:centerX,centerY,和area。另外,它還有一個方法叫做transform()。前三行是這個類的構造器。
但是它看起來不像一個類
你會想Figure()看起來不像一個類,而更像一個JavaScript的函數。那麼為什麼Figure()定義的是個類?

嚴格的說,Figure()函數沒有定義一個類,但是它仿造了一個。它實際上建立了一個對象,在括弧裡的代碼使這個對象的構造器。JavaScript的對象支援是很基礎的,它並不區分類和對象。
這就引到了問題為什麼Figure()函數建立的是一個對象。對象是可以有屬性和方法的。基本上,因為Figure()函數同時包含了屬性和方法,它就是個對象。在JavaScript裡,所有的函數即是對象又是可調用的代碼塊。這不像它聽起來的那樣容易被誤解。要建立一個Figure()類/對象,你只用使用以下句法:
MyFigure = new Figure();
你也可以把Figure()函數當作代碼塊調用,就像這樣:
figValue = Figure();
變數figValue沒有被定義是因為代碼塊Figure()沒有返回任何值。如果你把return(this.area)加到函數的最後一行,figValue就會有個值0。所以figValue是個類型數字,MyFigure是對象 Rectangle的執行個體。
為什麼所有的變數前面都一個“this”?

這個關鍵字this表示這是對象的執行個體變數,可以使用MyFigure.centerX從對象外部存取。要讓變數成為私人變數,去掉首碼this就行了。this.transform = transform這一行讓方法成為公用方法。這個方法通過MyFigure.transform(100,100,0)調用。

這些類有層次之分嗎?

另一個好問題的是JavaScript的類是否有層次之分。回答是肯定有。我們來仔細看看是怎麼做到分層的。我們可以定義一個Rectangle子類,並把Figure作為父類:

function Rectangle(startX, startY, endX, endY) {
this.width = endX - startX;
this.height = endY - startY;
this.centerX = (endX + startX)/2;
this.centerY = (endY + startY)/2;
this.computeArea = computeArea;
function computeArea() {
this.area = this.width*this.height;
} }
Rectangle.prototype = new Figure();

Rectangle對象是用4個自變數建立的,前四行是構造器。 Rectangle類包含了一個方法: computeArea()。最後一行Rectangle.prototype = new Figure();,把Rectangle類定義為從Figure類繼承來的子類。
然我來解釋一下prototype(原型)。每個物件建構器都有prototype屬性;這是用來給所有的對象增加新屬性和方法的。這就是為什麼原型被用來實現繼承:child.prototype = new parent();。通過原型,父物件的所有屬性和方法都被添加到子物件上。
要注意this.centerX,this.centerY,和area是Rectangle類中所使用的屬性,但是它們是 Figure父類的屬性。和Rectangle類相似,Circle類可以被定義成Figure類的原型。這種父子關係可以按你需要來定義深度;你可以建立另一個Rectangle的子類。
我如何建立一個類的執行個體?

在JavaScript裡建立一個類的執行個體很容易:
rect = new Rectangle(100,100,900,800);
這就建立了Rectangle類型的一個對象。Rectangle的構造器在屬性width, height, centerX, 和centerY中填入了值。rect.area屬性的值是零(0)。使用這個命令就能調用area方法:
rect.computeArea();
rect.area的值現在是560,000。要調用transform方法使用:
rect.transform(100,200,0);

父和子物件的屬性可以像這樣訪問到:
var ar = rect.area;
var wi = rect.width;

我能超越屬性和方法嗎?

就像你在Java中的一樣,你可以超越屬性和方法。在子類中定義的屬性或者方法可以超越同名的父類的屬性和方法。
和全域變數互動
JavaScript也支援全域變數的使用。在以下程式碼片段中測試一下g_area變數的範圍:
<HTML>
<SCRIPT>
var g_area = 20;
function Figure() {

this.area=g_area;

}
function Rectangle(){ … }
Rectangle.prototype = new Figure();
function test(){
g_area = 40;
rect = new Rectangle();
alert(rect.area);
}
</SCRIPT>
<BODY onLoad = 'test()'/>
</BODY>
</HTML>
rect.area的值是20(不是你預計的40),這是因為Rectangle對象是Figure對象的原型,這種關係在test()被調用以前就被定義了。要使用g_area的新值,你需要用以下的方法:

function test() {
g_area = 40;
Rectangle.prototype = new Figure();
rect = new Rectangle();
alert(rect.area);
}

對於所有的Rectangle的新執行個體,這將改變area屬性的值。或者,你可以使用這種方法:function test() {
g_area = 40;
rect = new Rectangle();
Rectangle.prototype.area = g_area;
alert(rect.area);
}

這將改變Rectangle所有現存的以及新執行個體的area屬性的值。
結論

為了效仿OO開發,JavaScript提供了必需的繼承、封裝和超越屬性,儘管它不支援介面和方法的過載。如果你是剛接觸到OO開發,用它試試。OO概念允許開發人員將一組資料和相關操作集中入一個對象。這在管理瀏覽器事件和管理瀏覽器內SVG圖時很有用

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.