从子对象修改原型上的字段

时间:2013-05-14 20:29:17

标签: javascript inheritance prototype field dry

这是一个清洁问题。

我正在使用原型实现基本继承以保持我的代码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();

2 个答案:

答案 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)

将属性存储在本地对象上,并在原型函数中引用它们。您不希望将状态保留在原型对象中,这应该只适用于函数(或者必要的“静态”字段)。

http://jsfiddle.net/C7aPQ/2/

//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);
        }
    };
}