0

这是一个清洁问题。

我正在使用原型来实现基本继承以保持我的代码干燥,我有一些原型用于所有意图和目的抽象(预计它们不会在被设置为其他对象的原型之外被实例化)和它们包含一些“子”对象将调用的代码。问题是原型中的函数依赖于原型的一些字段。更新子对象上的字段显然不会修改原型的字段。我想避免打电话

childObject.prototype.field = foo;

因为继承越深入就越混乱。

下面我粘贴了一个示例来解释我正在尝试做的事情。你可以在这里看到它在 jsfiddle 上运行。

//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();
4

2 回答 2

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!"
}

演示:http: //jsfiddle.net/DhbgE/

我只需要更改它,以便两个构造函数具有不同的方法名称。如果我们给出AnnoyingPrinter一个.print()方法,它会从Printer.

于 2013-05-14T20:49:44.300 回答
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);
        }
    };
}
于 2013-05-14T20:40:21.603 回答