2016-02-05 11 views
0

我有幾個JS對象。他們可以有任何結構:製作一個JS對象的副本,改變給定鍵的出現

{ 
    name: "first", 
    _ref_id: 1234, 
    spec: { 
    _ref_id: 2345, 
    data: "lots of data" 
    } 
} 

{ 
    name: 'second', 
    _ref_id: 5678, 
    container: { 
    _ref_id: 6789, 
    children: [ 
     {_ref_id: 3214, name: 'Bob'} 
     {_ref_id: 1111, name: 'Mark'} 
     {_ref_id: 2222, name: 'Frank'} 
    ] 
    } 
} 

問題:

我需要這個對象,但具有不同_ref_ids一個副本。

創作中的「第一」反對我看起來像這樣的:

first = { 
    name: "first", 
    _ref_id: uuid.v4(), 
    spec: { 
    _ref_id: uuid.v4(), 
    data: "lots of data" 
    } 
} 

所以我知道該對象的結構,當我創建它,但再往下的地方鏈,我想作這個對象的副本我沒有訪問權限,我不知道這個對象的結構是什麼,我擁有的是它自己的對象。因此,應對後「第一」我想有:

{ 
    name: "first", 
    _ref_id: 8888, 
    spec: { 
    _ref_id: 9999, 
    data: "lots of data" 
    } 
} 

我想,而不是對象創建期間定義_ref_id一個簡單的價值排序memoized功能:

refId(memoized = true){ 
    var memo = {} 
    return() => { 
    if(!memoized) memo = {} 
    if(memo['_ref_id']) 
     return memo._ref_id 
    else { 
     memo._ref_id = uuid.v4() 
     return memo._ref_id 
    } 
    } 
} 

所以我可以創建它:

first = { 
    name: "first", 
    _ref_id: refId(), 
    spec: { 
    _ref_id: refId(), 
    data: "lots of data" 
    } 
} 

,並更改first._ref_idfirst._ref_id()每當我tryi ng來訪問它的值。

但我不知道如何重置記憶變量從應對函數內,或者如果這甚至是可能的?

有沒有人有類似的問題?也許有不同的解決方法?

PS:

我使用lodash和immutable.js在這個項目,但我還沒有找到這個特殊任務的任何輔助功能。

+0

我不熟悉,記憶化,但我看不出它如何幫助解決你的問題。我會採取深層複製方法,在此期間我會尋找「瞬態場」來重新實現它,而不是複製它。 – Aaron

+0

memoization只是當我** first._ref_id()**重複同一個對象,我總是會得到相同的結果。但如果以某種方式,我將'注入'/更改memoized變量的值之間的新值將被生成的調用。但我的思維方式可能完全錯誤。你能否提供你的解決方案的例子? – Kocur4d

+0

當然,在它上面工作 – Aaron

回答

1

Most elegant way to clone a JS object啓發,用支票爲_ref_id領域:

function deepCopyWithNewRefId(obj) { 
    if (null == obj || "object" != typeof obj) return obj; 
     var copy = obj.constructor(); 
     for (var attr in obj) { 
     if (obj.hasOwnProperty(attr)) { 
      if (attr == "_ref_id") { 
       copy[attr] = uuid.v4(); 
      } else { 
       copy[attr] = deepCopyWithNewRefId(obj[attr]); 
      } 
     } 
    } 
    return copy; 
} 

其使用的日誌:

var uuid = { v4 : function(){ return Math.random()} }; 
var first = { 
    name: "first", 
    _ref_id: uuid.v4(), 
    spec: { 
    _ref_id: uuid.v4(), 
    data: "lots of data" 
    } 
}; 
console.log(first._ref_id); 
console.log(first.spec._ref_id); 
var second = deepCopyWithNewRefId(first); 
console.log(second); 
console.log(second._ref_id); 
console.log(second.spec._ref_id); 
// the printed values are not the same. The rest of the object is 
+0

很酷,對於我運行的所有示例而言,它們都非常合適。我會等待幾天,接受它作爲答案,我只是非常感興趣,看看它是否可以用不同的方法完成。我會在週末做更多的研究。非常感謝你的隊友。 – Kocur4d

+0

不客氣! JS中通過使用JSON.parse/JSON.stringify至少還有另一種方法來深入複製對象,其中JSON.parse方便地接受一個回調方法,該方法將授予它更改_ref_id字段值的可能性。代碼將更加簡潔,但我讀過它的效率也低得多。 – Aaron

+0

@Aaron恕我直言,使用序列化來複制對象是可怕的。我也看到它也用在HTML上,但它不對! – Alnitak

相關問題