Search code examples
javascriptoopdesign-patternsclone

javascript: private members and read-only properties


SCENARIO

I have got this class:

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}

Question

Everything works right. But if I do this:

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

the private member collection is eventually modified. That is unexpected (and unwanted!).

  • What is wrong?
  • How to make get() to return a copy of the collection member, and not the member itself?

EDIT

I have read this question. So cloning the collection member could do the job. Is there in design patterns another way to mamage private members and the related read-only properties?


Solution

  • Nothing is wrong this should be standard Javascript behavior( i think it is related with this JS closure stuff). :)

    You would have to Clone the Object manually(i think), if you dont want to use jQuery and stuff... and a shallow copy is enough

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

    for DeepCopies and stuff you would have to clone those Properties or write a Function, which you could attach to the object prototype, and call clone on properties and so on.... In my opinion for Deepcopies its probaly better to go with jQuery, and even more so if you are using it in your Page/Project/...