簡體   English   中英

從子對象修改原型上的字段

[英]Modifying a field on a prototype from a child object

這是清潔問題。

我正在使用原型來實現基本繼承以使代碼保持DRY,我有一些原型適用於所有意圖和目的(不希望將它們實例化為其他對象的原型之外),並且它們包含“子”對象將調用的一些代碼。 問題在於原型中的功能依賴於原型的某些字段。 在子對象上更新字段顯然不會修改原型的字段。 我想避免打電話

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

這是原型繼承的典型模式。

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蒙上陰影。

而是將屬性存儲在本地對象上,並在原型函數中引用它們。 您不希望將狀態保留在原型對象中,而實際上應該僅用於函數(或在必要時使用“靜態”字段)。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM