JavaScript之OOP編程,javascriptoop

來源:互聯網
上載者:User

JavaScript之OOP編程,javascriptoop

定義一個對象的最簡單的方法

var car = {color:"red",drive:function() {alert(this.color + " car moved");}}
這個方法不是在非常有用,因為它建立了一個單獨的對象,而這個對象和任何常見的資料結構沒有任何聯絡,為了建立第二個car執行個體,必須重新定義它的結構.


通過建構函式建立一個新對象

function Car() {this.color = "red";this.drive = function(){alert(this.color + " car moved");}}var car = new Car();car.drive();

JavaScript中的每個函數都有一個稱為prototype的屬性.如果某個函數被用作建構函式,則這個屬性會被自動通過new調用建立對象的原型

function Car() {this.color = "red";}Car.prototype.drive = function(){alert(this.color + " car moved");}var car = new Car();car.drive();

對prototype屬性所做的任何更改能夠應用於通過new Car()構造的每一個對象,不管它是在更改之前還是更改後建立.為Car.prototype 添加新函數.對於共用相同原型的每一個對象,該函數都可以立即使用,無論它是在更改之前或是之後構造,具體如下:

// 更新原型function Car(color) {this.color = color;}Car.prototype.drive = function(){alert(this.color + " car is driving");}var car1 = new Car("red");alert(car1.__proto__ === Car.prototype); // truecar1.drive();// 為原型添加新的函數Car.prototype.stop = function(){alert(this.color + " car has stopped");}var car2 = new Car("blue");// 共用同一對象原型的對象alert(Object.getPrototypeOf(car1) === Object.getPrototypeOf(car2));  // true// 這兩個對象現在都能訪問這個新的方法car2.stop();car1.stop();

物件導向的很重要一個特性就是繼承了,這裡只要介紹通過原型鏈繼承

// 繼承的基本設定function Car(color) {this.color = color;}Car.prototype.drive = function(){alert(this.color + " car is driving");}Car.prototype.turn = function(direction) {alert(this.color + " car turns " + direction);}Car.prototype.stop = function() {alert(this.color + " car has stopped");}// 消防車function FirTruck() {}FirTruck.prototype.turnCannon = function(direction) {alert("Cannon moves to the " + direction);}var truck = new FirTruck();// 因為Car.prototype 並不在truck對象的原型鏈中// 因此方法move()並不可用truck.move();truck.turnCannon("right");

JavaScript中有一個很特殊的Object.create(proto, properties)方法, 注:IE8及以下不支援
它可以用來建立一個新的空白對象並將其原型設定為proto


function Car(color) {this.color = color;}Car.prototype.move = function(){alert(this.color + " car is driving");}Car.prototype.turn = function(direction) {alert(this.color + " car turns " + direction);}Car.prototype.stop = function() {alert(this.color + " car has stopped");}if(!Object.create){        // 相容性處理        FireTruck.prototype = Car.prototype;}else{FireTruck.prototype = Object.create(Car.prototype);}function FireTruck() {}// 檢查,以防萬一//alert(Object.getPrototypeOf(FireTruck.prototype) === Car.prototype);// 如果為true// 則Car.prototype被添加到鏈中FireTruck.prototype.turnCannon = function(direction){alert("Cannon moves to the " + direction);}var truck = new FireTruck();// 現在可以工作了,因為Car.prototype已經在truck對象的原型鏈中truck.move();truck.turnCannon("right");

代碼可以運行,但其輸出還是存在一些問題

true
undefined car is driving
Cannon moves to the right


小汽車的color現在可以通過Car的建構函式進行設定.建構函式本身沒有執行,所以其color顯示為undefined.這個問題很好解決,修改FireTruck建構函式,在其中添加對Car建構函式的調用,這樣Car就可以初始化它自己的物件變數

function FireTruck() {Car.call(this, "red");}
再次運行這段代碼,欣賞一下正確的輸出


即使該代碼能夠成功運行,但仍有一個小問題需要解決.當這個新函數建立時,它的prototype屬性並不為空白.它有一個稱為constructor的屬性將引用函數本身,當調用

    FireTruck.prototype = Object.create(Car.prototype);

時,該屬性丟失,因為這個建立的對象並不具有自己的屬性.可以將丟失的屬性作為第二個參數傳遞給create


FireTruck.prototype = Object.create(Car.prototype, {constructor: {value: FireTruck,         // 和FireTruck.prototype.constructor一樣enumerable: false,writable: true,configurable: true}});
這裡的constructor並不是通常的屬性.當對象的鍵值進行迴圈時,它不會出現,但可以通過名稱直接存取.通過給create()的第二個參數傳遞屬性"描述符"可以取得相同的效果
描述符具有如下所示的幾個欄位
    value: 初始值
    enumerable: 如果屬性顯示在對象屬性的列表中, 在像for...in 這樣的迴圈或Object.keys中
    writable: 如果屬性可以被指派一個不同的值
    configurable: 如果描述符定義的規則可以被修改或其屬性可以刪除,則為true
這樣就可以模模擬實的 constructor 的行為


 最終版本的的繼承樣本

function extend(subConstructor, superConstructor) {if(!Object.create){subConstructor.prototype = superConstructor.prototype;subConstructor.constructor = {value: FireTruck,         // 和FireTruck.prototype.constructor一樣enumerable: false,writable: true,configurable: true}}else{subConstructor.prototype = Object.create(superConstructor.prototype, {constructor: {value: FireTruck,         // 和FireTruck.prototype.constructor一樣enumerable: false,writable: true,configurable: true}});}}function Car(color) {this.color = color;}Car.prototype.move = function(){alert(this.color + " car is driving");}Car.prototype.turn = function(direction) {alert(this.color + " car turns " + direction);}Car.prototype.stop = function() {alert(this.color + " car has stopped");}function FireTruck() {Car.call(this, "red");}extend(FireTruck, Car);FireTruck.prototype.turnCannon = function(direction){alert("Cannon moves to the " + direction);}var truck = new FireTruck();truck.move();truck.turnCannon("right");



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.