【问题标题】:javascript: private members and read-only propertiesjavascript:私有成员和只读属性
【发布时间】:2013-02-15 00:38:40
【问题描述】:

场景

我有这门课:

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 成员可以完成这项工作。设计模式中是否有另一种方法来管理私有成员和相关的只读属性?

【问题讨论】:

    标签: javascript oop design-patterns clone


    【解决方案1】:

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

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

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

    对于 DeepCopies 和其他东西,您必须克隆这些属性或编写一个函数,您可以将其附加到对象原型,并在属性上调用克隆等等...... 在我看来,对于 Deepcopies,它可能会更好地使用 jQuery,如果您在 Page/Project/...中使用它更是如此。

    【讨论】:

      【解决方案2】:

      请参阅this 答案。

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

      【讨论】:

        【解决方案3】:

        在 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);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-18
          相关资源
          最近更新 更多