簡體   English   中英

Javascript原型繼承

[英]Javascript prototypal inheritance

我正在通過遇到的一個問題來嘗試Javascript繼承的幾個方面:

創建一個預訂系統來預訂飛機座位或酒店房間。 它為飛機或酒店的特定區域收取各種費用。 例如,頭等艙的費用要比教練多。 酒店的客房設有頂樓套房,價格更高。 跟蹤何時有空房間並可以預定房間。

我正在處理酒店房間的問題。

我已經決定使用一個具有一個名為“ duration”的數據成員的單一房間基礎對象,該成員跟蹤房間預訂的天數,並提供兩種方法:book和checkout。

我有一個繼承自SingleRoom的派生對象“ SingleRoom”。

這是代碼:

    function Room(duration){
    this.duration = duration;
}
Room.prototype.book = ()=>{
    if (this.prototype.count > 0){
        this.prototype.count -= 1;
        return true;
    }
    else {
        return false;
    }
}

Room.prototype.checkOut = ()=>{
    this.prototype.count += 1;
    console.log("Room checked out");
}

function SingleRoom(duration){
    this.price = 1000;
}
SingleRoom.prototype = new Room();
SingleRoom.prototype.constructor = SingleRoom;
SingleRoom.prototype.count = 3;
var sr1 = new SingleRoom(2);
if(sr1.book() === false){
    console.log("Could not book room");
}

我在“ this.prototype.count”處收到以下錯誤: 無法讀取未定義的屬性計數

知道是什么問題嗎?

謝謝!

您只應在構造函數上使用prototype屬性。 這是對的:

SingleRoom.prototype = new Room();
SingleRoom.prototype.constructor = SingleRoom;
SingleRoom.prototype.count = 3;

但是您不應該在單個對象上使用它。 當您訪問未在直接對象上定義的屬性時,將自動搜索原型鏈。 您在this.prototype.count具有this.prototype.count地方都將其更改為this.count ,它將正常工作。

您將函數與實例(或至少與函數一起使用的屬性與與實例一起使用的屬性混淆;這確實很容易做到)。 prototype屬性用於構造函數。 它是指將被指定為通過該構造函數創建的對象的基礎原型(在規范中稱為[[Prototype]] )的[[Prototype]]對象。 它不是(令人困惑!)對對象原型的引用。 為了得到它(規范稱為[[Prototype]] ),您可以使用Object.getPrototypeOf(theObject) ,但是這種情況相對來說很少見。

這可能有助於闡明這種關系:

 function Thing(name) { this.name = name; } Thing.prototype.say = function() { console.log(this.name); }; var t = new Thing("Ben"); console.log(t.prototype); // undefined, `t` has no `prototype` property console.log(Thing.prototype); // an object with `say` t.say(); // "Ben" console.log(Object.getPrototypeOf(t) === Thing.prototype); // true 

另一個問題是您正在使用箭頭函數來定義原型上的函數,這將無法正常工作。 箭頭功能的一點是,他們關閉了this ,但是對於原型功能,你想this一套由函數是如何被調用。

如果您使用的是ES2015(例如,使用Babel或類似語言進行轉譯),則可以使用美觀,新,易用的語法。 我不得不猜測應該count什么。 我把它放在Room實例上:

class Room {
    constructor(duration){
        this.duration = duration;
        this.count = 3;
    }

    book() {
        if (this.count > 0) {
            this.count -= 1;
            return true;
        }
        else {
            return false;
        }
    }

    checkOut() {
        this.count += 1;
        console.log("Room checked out");
    }
}

class SingleRoom extends Room {
    constructor(duration){
        super(duration);
        this.price = 1000;
    }
}

var sr1 = new SingleRoom(2);
if (sr1.book() === false){
    console.log("Could not book room");
}

如果您想使用ES5,請參考以下翻譯:

function Room(duration) {
    this.duration = duration;
    this.count = 3;
}
// Note we *don't* use arrow functions for prototype functions; it's important
// for them to get `this` by how they're called.
Room.prototype.book = function() {
    if (this.count > 0) {
        this.count -= 1;
        return true;
    }
    else {
        return false;
    }
};
Room.prototype.checkOut = function() {
    this.count += 1;
    console.log("Room checked out");
};

// Derive SingleRoom from Room
function SingleRoom(duration) {
    Room.call(this, duration);  // Necessary to init Room
    this.price = 1000;
}
SingleRoom.prototype = Object.create(Room.prototype); // NOT `new Room()`
SingleRoom.prototype.constructor = SingleRoom;

var sr1 = new SingleRoom(2);
if (sr1.book() === false){
    console.log("Could not book room");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM