1

從Java背景來看,我期望類的實例的基類中的屬性與使用相同基類的其他類實例是唯一的。使用JavaScript原型繼承的意外共享數據

在JavaScript中,存儲在「基類」中的任何屬性似乎都在該「基類」的各種實例之間共享。舉例來說,在這裏看到:

http://jsfiddle.net/4waQV/

正如你所看到的,BaseView.settings通過兩個ViewOneViewTwo訪問。在一個實例中更改BaseView.settings中的值會影響另一個實例中的值。

如果我將settings: {}BaseView中撥出並轉換爲ViewOneViewTwo,則所有操作都按我期望的方式進行。

http://jsfiddle.net/4waQV/1/

不過,我不想弄亂ViewOneViewTwo有額外的屬性。所以,我可以動態裏面BaseView.setProp()創建this.settings

http://jsfiddle.net/4waQV/2/

是否有更好的方法來解決這個問題,或者這是一個很好的解決方案?

請注意,我在本例中使用Backbone.JS視圖,但我期望任何JavaScript原型繼承解決方案的結果都是相似的。你可以看到,骨幹網使用創造原型的繼承相當典型方法:

https://github.com/documentcloud/backbone/blob/0.3.3/backbone.js#L870

https://github.com/documentcloud/backbone/blob/0.3.3/backbone.js#L955

+1

參見http:/ /stackoverflow.com/q/6362214/783219 – Prusse

+0

@Prusse,謝謝,看起來相關並且有幫助 – Tauren

回答

1

這裏的問題是,設置從基本視點繼承;繼承,不復制。如果它是一個字符串值,它本質上將被複制,但在JavaScript中,數組和對象是通過引用傳遞的,而不是通過值傳遞的,所以當對象實例化時它最終指向同一個對象。

修復的方法是建立在你的基本視點的初始化方法並添加以下行:

this.settings = {}; 

那麼當然你要確保你調用基本視點從每個子視圖的初始化。你可以這樣做:

BaseView.prototype.initialize.apply(this, arguments); 

例如, http://jsfiddle.net/taxilian/PDmN8/1/

請注意,這種初始化成員的方法需要在所有數組或對象成員上完成,否則您將遇到同樣的問題。你也可以創建一個構造函數並在那裏執行,但是我從來沒有真正清楚在Backbone類中如何工作,並且沒有花時間真正地坐下來弄清楚它=]