WIKI使用導航
站長百科導航
站長專題
- 網(wǎng)站推廣
- 網(wǎng)站程序
- 網(wǎng)站賺錢
- 虛擬主機
- cPanel
- 網(wǎng)址導航專題
- 云計算
- 微博營銷
- 虛擬主機管理系統(tǒng)
- 開放平臺
- WIKI程序與應用
- 美國十大主機
通過prototype屬性建立面向對象的JavaScript
導航: 上一頁 | ASP | PHP | JSP | HTML | CSS | XHTML | aJAX | Ruby | JAVA | XML | Python | ColdFusion
JavaScript通過一種鏈接機制來支持繼承,而不是通過完全面向對象語言(如Java)所支持的基于類的繼承模型。每個JavaScript對象都有一個內(nèi)置的屬性,名為prototype。prototype屬性保存著對另一個JavaScript對象的引用,這個對象作為當前對象的父對象。
當通過點記法引用對象的一個函數(shù)或屬性時,倘若對象上沒有這個函數(shù)或屬性,此時就會使用對象的prototype屬性。當出現(xiàn)這種情況時,將檢查對象prototype屬性所引用的對象,查看是否有所請求的屬性或函數(shù)。如果prototype屬性引用的對象也沒有所需的函數(shù)或屬性,則會進一步檢查這個對象(prototype屬性引用的對象)的prototype屬性,依次沿著鏈向上查找,直到找到所請求的函數(shù)或屬性,或者到達鏈尾,如果已經(jīng)到達鏈尾還沒有找到,則返回undefined。從這個意義上講,這種繼承結構更應是一種“has a”關系,而不是“is a”關系。
如果你習慣于基于類的繼承機制,那么可能要花一些時間來熟悉這種prototype機制。prototype機制是動態(tài)的,可以根據(jù)需要在運行時配置,而無需重新編譯。你可以只在需要時才向對象增加屬性和函數(shù),而且能動態(tài)地把單獨的函數(shù)合并在一起,來創(chuàng)建動態(tài)、全能的對象。對prototype機制的這種高度動態(tài)性可謂褒貶不一,因為這種機制學習和應用起來很不容易,但是一旦正確地加以應用,這種機制則相當強大而且非常健壯。
這種動態(tài)性與基于類的繼承機制中的多態(tài)概念異曲同工。兩個對象可以有相同的屬性和函數(shù),但是函數(shù)方法(實現(xiàn))可以完全不同,而且屬性可以支持完全不同的數(shù)據(jù)類型。這種多態(tài)性使得JavaScript對象能夠由其他腳本和函數(shù)以統(tǒng)一的方式處理。
圖5-15顯示了實際的prototype繼承機制。這個腳本定義了3類對象:Vehicle、Sports-
Car和CementTruck。Vehicle是基類,另外兩個類由此繼承。Vehicle定義了兩個屬性:wheelCount和curbWeightInPounds,分別表示Vehicle的車輪數(shù)和總重量。JavaScript不支持抽象類的概念(抽象類不能實例化,只能由其他類擴展),因此,對于Vehicle基類,wheelCount默認為4,curbWeightInPounds默認為3 000。
圖5-15 Vehicle、SportsCar和CementTruck對象之間的關系
注意,這個UML圖展示了SportsCar和CementTruck對象覆蓋了Vehicle的refuel和mainTasks函數(shù),因為一般的Vehicle、SportsCar(賽車)和CementTruck(水泥車)會以不同的方式完成這些任務。SportsCar與Vehicle的車輪數(shù)相同,所以SportsCar的wheelCount屬性不會覆蓋Vehicle的wheelCount屬性。CementTruck的車輪數(shù)和重量都超過了Vehicle,所以CementTruck的wheelCount和curbWeightInPounds屬性要覆蓋Vehicle的相應屬性。
代碼清單5-2包含了定義這3個類的JavaScript代碼。要特別注意如何在對象定義中對屬性和函數(shù)附加prototype關鍵字,還要注意每個對象由一個構造函數(shù)定義,構造函數(shù)與對象類型同名。
代碼清單5-2
inheritanceViaPrototype.js
/* Constructor function for the Vehicle object */
function Vehicle() { }
/* Standard properties of a Vehicle */
Vehicle.prototype.wheelCount = 4;
Vehicle.prototype.curbWeightInPounds = 4000;
/* Function for refueling a Vehicle */
Vehicle.prototype.refuel = function() {
return "Refueling Vehicle with regular 87 octane gasoline";
}
/* Function for performing the main tasks of a Vehicle */
Vehicle.prototype.mainTasks = function() {
return "Driving to work, school, and the grocery store";
}
/* Constructor function for the SportsCar object */
function SportsCar() { }
/* SportsCar extends Vehicle */
SportsCar.prototype = new Vehicle();
/* SportsCar is lighter than Vehicle */
SportsCar.prototype.curbWeightInPounds = 3000;
/* SportsCar requires premium fuel */
SportsCar.prototype.refuel = function() {
return "Refueling SportsCar with premium 94 octane gasoline";
}
/* Function for performing the main tasks of a SportsCar */
SportsCar.prototype.mainTasks = function() {
return "Spirited driving, looking good, driving to the beach";
}
/* Constructor function for the CementTruck object */
function CementTruck() { }
/* CementTruck extends Vehicle */
CementTruck.prototype = new Vehicle();
/* CementTruck has 10 wheels and weighs 12,000 pounds*/
CementTruck.prototype.wheelCount = 10;
CementTruck.prototype.curbWeightInPounds = 12000;
/* CementTruck refuels with diesel fuel */
CementTruck.prototype.refuel = function() {
return "Refueling CementTruck with diesel fuel";
}
/* Function for performing the main tasks of a SportsCar */
CementTruck.prototype.mainTasks = function() {
return "Arrive at construction site, extend boom, deliver cement";
}
代碼清單5-3是一個很小的Web頁面,展示了這3個對象的繼承機制。這個頁面只包含3個按鈕,每個按鈕創(chuàng)建一個類型的對象(Vehicle、SportsCar或CementTruck),并把對象傳遞到describe函數(shù)。describe函數(shù)負責顯示各個對象的屬性值,以及對象函數(shù)的返回值。注意,describe方法并不知道它描述的對象是Vehicle、SportsCar,還是CementTruck,它只是認為這個對象有適當?shù)膶傩院秃瘮?shù),并由這個對象返回自己的值。
代碼清單5-3
inheritanceViaPrototype.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>JavaScript Inheritance via Prototype</title>
<script type="text/javascript" src="inheritanceViaPrototype.js"></script>
<script type="text/javaScript">
function describe(vehicle) {
var description = "";
description = description + "Number of wheels: " + vehicle.wheelCount;
description = description + "\n\nCurb Weight: " + vehicle.curbWeightInPounds;
description = description + "\n\nRefueling Method: " + vehicle.refuel();
description = description + "\n\nMain Tasks: " + vehicle.mainTasks();
alert(description);
}
function createVehicle() {
var vehicle = new Vehicle();
describe(vehicle);
}
function createSportsCar() {
var sportsCar = new SportsCar();
describe(sportsCar);
}
function createCementTruck() {
var cementTruck = new CementTruck();
describe(cementTruck);
}
</script>
</head>
<body>
<h1>Examples of JavaScript Inheritance via the Prototype Method</h1>
<br/><br/>
<button onclick="createVehicle();">Create an instance of Vehicle</button>
<br/><br/>
<button onclick="createSportsCar();">Create an instance of SportsCar</button>
<br/><br/>
<button onclick="createCementTruck();">Create an instance of CementTruck</button>
</body>
</html>
分別創(chuàng)建3個對象,并用describe函數(shù)描述,結果如圖5-16所示。
圖5-16 創(chuàng)建Vehicle、SportsCar和CementTruck 對象并使用describe函數(shù)分別描述的結果