2013-02-28 24 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); 
} 
相关问题