SCENARIO
我有这门课:
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
成员可以完成这项工作。在设计模式中是否有另一种方法来保护私有成员和相关的只读属性?
答案 0 :(得分:2)
没有什么是错的,这应该是标准的Javascript行为(我认为它与这个JS闭包的东西有关)。 :)
你必须手动克隆对象(我认为),如果你不想使用jQuery和东西......并且浅拷贝就足够了
function clone(obj)
{
var cloneObj = {};
for(var prop in obj )
{
cloneObj [prop] = obj[prop];
}
return cloneObj;
}
对于DeepCopies和东西你必须克隆那些属性或编写一个函数,你可以附加到对象原型,并在属性上调用克隆等等.... 在我看来,对于Deepcopies来说,最好使用jQuery,如果你在你的Page / Project /...中使用它,那就更好了。
答案 1 :(得分:0)
请参阅this回答。
this.get = function() {
return jQuery.extend({}, collection);
});
答案 2 :(得分:0)
在javascript中,对象应该通过引用传递而不是传递值。所以,有一个参考。您可以修改get函数,如下所示将对象序列化为JSON字符串,然后将其反序列化为对象以克隆对象。所有没有任何第三方库的浏览器都支持JSON.stringify
和JSON.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);
}