繁体   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