这是一个清洁问题。
我正在使用原型(prototype)来实现基本继承,以保持代码干燥,我有一些原型(prototype),它们对于所有意图和目的都是抽象的(预计它们不会在被设置为其他原型(prototype)的原型(prototype)之外被实例化)对象)并且它们包含“子”对象将调用的一些代码。问题在于原型(prototype)中的函数依赖于原型(prototype)的某些字段。更新子对象上的字段显然不会修改原型(prototype)的字段。我想避免打电话
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();
最佳答案
这是原型(prototype)继承的典型模式。
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!"
}
演示: http://jsfiddle.net/DhbgE/
我只需更改它,以便两个构造函数具有不同的方法名称。如果我们为 AnnoyingPrinter
提供一个 .print()
方法,它会隐藏 Printer
中的方法。
关于javascript - 从子对象修改原型(prototype)上的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16552279/