我已经阅读了有关 JavaScript 原型继承的页面和页面,但我没有找到任何使用涉及验证的构造函数来解决的问题。我已经设法让这个构造函数工作,但我知道它并不理想,即它没有利用原型继承:
function Card(value) {
if (!isNumber(value)) {
value = Math.floor(Math.random() * 14) + 2;
}
this.value = value;
}
var card1 = new Card();
var card2 = new Card();
var card3 = new Card();
这会产生三个具有随机值的 Card 对象。但是,我理解它的方式是,每次我以这种方式创建一个新的 Card 对象时,它都会复制构造函数代码。我应该改用原型继承,但这不起作用:
function Card(value) {
this.value = value;
}
Object.defineProperty( Card, "value", {
set: function (value) {
if (!isNumber(value)) {
value = Math.floor(Math.random() * 14) + 2;
}
this.value = value;
}
});
这也不起作用:
Card.prototype.setValue = function (value) {
if (!isNumber(value)) {
value = Math.floor(Math.random() * 14) + 2;
}
this.value = value;
};
一方面,我不能再打电话了new Card()
。相反,我必须调用var card1 = new Card(); card1.setValue();
这对我来说似乎非常低效和丑陋。但真正的问题是它将每个 Card 对象的 value 属性设置为相同的值。帮助!
编辑
根据 Bergi 的建议,我将代码修改如下:
function Card(value) {
this.setValue(value);
}
Card.prototype.setValue = function (value) {
if (!isNumber(value)) {
value = Math.floor(Math.random() * 14) + 2;
}
this.value = value;
};
var card1 = new Card();
var card2 = new Card();
var card3 = new Card();
这会产生三个具有随机值的 Card 对象,这很好,我可以稍后调用 setValue 方法。但是,当我尝试扩展课程时,它似乎没有转移:
function SpecialCard(suit, value) {
Card.call(this, value);
this.suit = suit;
}
var specialCard1 = new SpecialCard("Club");
var specialCard2 = new SpecialCard("Diamond");
var specialCard3 = new SpecialCard("Spade");
我现在得到错误this.setValue is not a function
。
编辑 2
这似乎有效:
function SpecialCard(suit, value) {
Card.call(this, value);
this.suit = suit;
}
SpecialCard.prototype = Object.create(Card.prototype);
SpecialCard.prototype.constructor = SpecialCard;
这是一个好方法吗?
最终编辑!
感谢 Bergi 和 Norguard,我终于找到了这个实现:
function Card(value) {
this.setValue = function (val) {
if (!isNumber(val)) {
val = Math.floor(Math.random() * 14) + 2;
}
this.value = val;
};
this.setValue(value);
}
function SpecialCard(suit, value) {
Card.call(this, value);
this.suit = suit;
}
Bergi 帮助我确定了我无法继承原型链的原因,Norguard 解释了为什么最好完全不要使用原型链。我喜欢这种方法,因为代码更干净,更容易理解。