1

设想

我有这门课:

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而不是成员本身?

编辑

我读过这个问题。所以克隆collection成员可以完成这项工作。设计模式中是否有另一种方法来管理私有成员和相关的只读属性?

4

3 回答 3

2

没有错,这应该是标准的 Javascript 行为(我认为它与这个 JS 闭包有关)。:)

你必须手动克隆对象(我认为),如果你不想使用 jQuery 和其他东西......并且浅拷贝就足够了

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

于 2013-02-28T17:47:51.327 回答
0

看到这个答案。

this.get = function() {
   return jQuery.extend({}, collection);
});
于 2013-02-28T17:45:10.050 回答
0

在 javascript 中,对象应该通过引用传递,而不是通过值传递。所以,有一个参考。您将如下修改 get 函数以将对象序列化为 JSON 字符串,然后将其反序列化回对象以克隆对象。JSON.stringify并且JSON.parse在没有任何 3rd 方库的所有浏览器中都受支持。

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);
}
于 2013-02-28T17:45:26.367 回答