2013-02-28 26 views
1

情景的javascript:私有成員和只讀屬性

我有這個類:

var AssocArray = function(){ 
    var collection = new Object(); 

    this.add = function(id, o){ 
     collection[id] = o; 
    } 

    this.remove = function(id){ 
     delete collection[id]; 
    } 

    this.getById = function(id){ 
     return collection[id]; 
    } 

    this.get = function(){ 
     var res = collection; 
     return res; 
    } 
} 

var myAssoc = new AssocArray(); 
myAssoc.add("11",{ "packageId": "11", "machineId": "1", "operationType": "Download"}); 
myAssoc.add("12",{ "packageId": "12", "machineId": "1", "operationType": "Download"}); 
myAssoc.add("14",{ "packageId": "14", "machineId": "1", "operationType": "Download" }); 

if(myAssoc.getById("20")) myAssoc.remove("20"); 
if(myAssoc.getById("11")) myAssoc.remove("11"); 

console.log(myAssoc.get()); //returns Object {12: Object, 14: Object} 

問題

一切工作的權利。但是,如果我這樣做:

(myAssoc.get())[10] = {}; 
console.log(myAssoc.get()); //returns Object {10: Object, 12: Object, 14: Object}!! 

私有成員collection最終修改。這是意想不到的(並且不需要!)。

  • 出了什麼問題?
  • 如何使get()返回副本collection成員,而不是成員本身?

編輯

我已閱讀本question。因此克隆collection會員可以完成這項工作。設計模式中是否存在另一種方式來隱藏私有成員和相關的只讀屬性?

回答

2

沒有什麼是錯的,這應該是標準的JavaScript行爲(我認爲這是與此相關的JS封閉的東西)。 :)

你將不得不手動(我認爲)克隆對象,如果你不想使用jQuery之類的東西......和淺拷貝足夠

function clone(obj) 
{ 
    var cloneObj = {}; 
    for(var prop in obj) 
    { 
     cloneObj [prop] = obj[prop]; 
    } 
    return cloneObj; 
} 

爲DeepCopies和東西你會必須克隆這些屬性或編寫一個函數,您可以附加到對象原型,並調用克隆的屬性等等。在我看來,對於Deepcopies而言,它更好地使用jQuery,甚至更好,如果你正在使用它在你的網頁/項目/ ...

0

在javascript中,對象應該通過引用而不是傳遞值。所以,有一個參考。你可以像下面那樣修改get函數來將對象序列化爲JSON字符串,然後將其反序列化爲對象來克隆一個對象。所有沒有任何第三方庫的瀏覽器都支持JSON.stringifyJSON.parse

this.get = function(){ 
var s = JSON.stringify(collection); 
return JSON.parse(s); 
} 

如果你已包括在你的網站的jQuery,你會利用$.extend功能。
參考:http://api.jquery.com/jQuery.extend/

this.get = function(){ 
return $.extend({}, collection); 
} 
相關問題