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

DeepCopies などの場合は、それらのプロパティを複製するか、関数を記述してオブジェクト プロトタイプにアタッチし、プロパティで clone を呼び出す必要があります。ページ/プロジェクト/...で使用している場合はなおさらです。

于 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.stringifyJSON.parse

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

Web サイトに jquery を組み込んでいる場合は、この$.extend機能を利用できます。
参考:http ://api.jquery.com/jQuery.extend/

this.get = function(){
 return $.extend({}, collection);
}
于 2013-02-28T17:45:26.367 に答える