[英]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.