这是一个清洁问题。
我正在使用原型实现基本继承以保持我的代码DRY,我有一些原型用于所有意图和目的摘要(预计它们不会被设置为其他原型的实例化。它们包含一些“子”对象将调用的代码。问题是原型中的函数依赖于一些原型的字段。更新子对象上的字段显然不会修改原型的字段。我想避免打电话
childObject.prototype.field = foo;
随着这种情况越来越混乱,继承越深入。
下面我贴了一个例子来解释我正在尝试做什么。您可以在jsfiddle here上看到它正在运行。
//Prints something once.
function Printer(text) {
this.text = text || "";
this.print = function () {
alert(text);
};
}
//Prints everything a set number of times
function AnnoyingPrinter(text, count) {
this.prototype = new Printer(text);
this.count = count || 1;
this.print = function () {
for (var i = 0; i < this.count; i++) {
this.prototype.print();
}
};
}
function doStuff() {
var annoyer = new AnnoyingPrinter("Hello world!", 2);
annoyer.print();
//Now I want to change the text without having to dig down into the prototype (particularly if I ever want to extend AnnoyingPrinter too)
annoyer.text = "Goodbye world!";
annoyer.print();
}
//Expected outcome:
//Hello world!
//Hello world!
//Goodbye world!
//Goodbye world!
//Actual outcome:
//Hello world!
//Hello world!
//Hello world!
//Hello world!
doStuff();
答案 0 :(得分:2)
这是原型继承的典型模式。
function Printer(text) {
this.text = text || "";
}
Printer.prototype.print = function() {
alert(this.text);
}
function AnnoyingPrinter(text, count) {
Printer.call(this, text);
this.count = count || 1;
}
AnnoyingPrinter.prototype = Object.create(Printer.prototype);
AnnoyingPrinter.prototype.printAll = function() {
for (var i = 0; i < this.count; i++) {
this.print();
}
}
然后,您的doStuff()
可以继续创建新的AnnoyingPrinter
,并致电print()
。
function doStuff() {
var annoyer = new AnnoyingPrinter("Hello world!", 2);
annoyer.printAll(); // "Hello world!" "Hello world!"
annoyer.text = "Goodbye world!";
annoyer.printAll(); // "Goodbye world!" "Goodbye world!"
}
DEMO: http://jsfiddle.net/DhbgE/
我只需要更改它,以便两个构造函数具有不同的方法名称。如果我们提供了AnnoyingPrinter
.print()
方法,则会隐藏Printer
中的方法。
答案 1 :(得分:1)
将属性存储在本地对象上,并在原型函数中引用它们。您不希望将状态保留在原型对象中,这应该只适用于函数(或者必要的“静态”字段)。
//Prints something once.
function Printer(text)
{
this.text = text || "";
this.print = function()
{
alert(this.text);
};
}
//Prints everything a set number of times
function AnnoyingPrinter(text,count)
{
this.prototype = new Printer(text);
this.text = text;
this.count = count || 1;
this.print = function()
{
for(var i =0;i<this.count;i++)
{
this.prototype.print.call(this);
}
};
}