javascript: private members and read-only properties

拟墨画扇 提交于 2019-12-08 05:49:05

问题


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?


回答1:


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/...




回答2:


See this answer.

this.get = function() {
   return jQuery.extend({}, collection);
});



回答3:


In javascript, object should be pass by reference instead of pass by value. So, there is a referencing. You would modify the get function as below to serialize the object to JSON string and then deserialize it back to object to clone an object. JSON.stringify and JSON.parse is supported in all browsers without any 3rd party library.

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

If you have included jquery in your web site, you would make use of the $.extend function.
Reference : http://api.jquery.com/jQuery.extend/

this.get = function(){
 return $.extend({}, collection);
}


来源:https://stackoverflow.com/questions/15142022/javascript-private-members-and-read-only-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!