簡體   English   中英

可以從實例更改原型對象

[英]Prototype object can be changed from instance

有人可以用一種明智的方式向我解釋一下:

function One() {}

One.prototype.obj = { key: 'value' };
One.prototype.str = 'string';

var inst1 = new One(),
    inst2 = new One();

// now let’s change some things in our second instance

inst2.obj.key = 'buh!';
inst2.str = 'buh!';

// ok, so what happens to our other instance?

console.log( inst1.str ); // Yields 'string' (unaffected, expected)
console.log( inst1.obj.key ); // Yields 'buh!' (!!)

console.log( One.prototype.obj.key ); // is also 'buh!'

看來,如果原型包含一個對象,則使用new關鍵字創建的實例具有該對象,但是如果更改了它,則還更改了該原型對象,從而影響了所有實例,例如同級繼承模式。

這是應該工作的方式嗎?

簡而言之,是的。 Javascript不會為您隱式復制對象,因此,在obj處創建對象文字時, One類的所有實例都可以通過引用直接引用它。 相反,您需要在構造函數中動態創建obj對象:

function One(){
  this.obj = {key:'value'};
}

另請參閱: javascript多維對象

實際上,JavaScript不會從原型中復制任何內容。 您在原型上定義的所有內容僅存在一次(在原型本身上),並且由於將相同的原型實例傳遞給所有對象而被重用。

當您訪問對象的屬性時,該對象將檢查是否已在其自身上定義。 如果是,它將返回與該屬性關聯的值。 如果不是這樣,它將把調用委托給它的原型,原型從現在開始對發生的事情負責。 這就是為什么Javascript中的“繼承”(代碼重用)更好地稱為委托的原因。

對於寫訪問,情況有所不同。 如果在對象上設置屬性,它將在本地“陰影”該值。 這就是為什么str屬性不受影響的原因,它實際上是在inst2對象上定義的。 但是,如果delete inst2.str並執行另一個console.log( inst2.str )您會注意到它將返回舊值。

PS:如果您想要防止這種情況發生的方法,請查看此教程: http : //kevlindev.com/tutorials/javascript/inheritance/index.htm

我建議閱讀全部內容,但是如果您只想吃點東西,請參閱“創建子類”部分中的KevLinDev.extend函數。

暫無
暫無

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

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