2017-06-22 49 views
-1

目標:複製兩個對象,完全 問題:使用Object.assign不做深副本如何編寫真正複製對象的deepMerge/deepClone函數?

我寫了一個deepMerge功能以下一些例子,我發現在這裏 - 這似乎並沒有真正「克隆」對象。當我修改源的屬性時,它會修改目標。

function isObject(item) { 
    return (item && typeof item === 'object' && !Array.isArray(item)); 
} 

function mergeDeep(target, source) { 
    if (isObject(target) && isObject(source)) { 
    Object.keys(source).forEach(key => { 
     if (isObject(source[key])) { 
     if (!(key in target)) { 
      Object.assign(target, { 
      [key]: source[key] 
      }); 
     } else { 
      mergeDeep(target[key], source[key]); 
     } 
     } else { 
     Object.assign(target, { 
      [key]: source[key] 
     }); 
     } 
    }) 
    } 
} 

let target = {}; 
let source = { 
    name: 'apple', 
    items: [{ 
    id: '1', 
    value: 'macintosh' 
    }] 
} 

mergeDeep(target, source); 
source.items[0].value = 'granny smith'; 
//expect target apple to still be 'macintosh' 
alert(target.items[0].value); //prints 'granny smith' 

下面的代碼:https://jsfiddle.net/q68z02pb/

+0

'目標[鍵] = mergeDeep(目標[鍵],源[鍵]);'? 'mergeDeep'不返回任何東西。 – PeterMader

+0

如果將其刪除,結果相同。 – antonpug

+1

如果你不想導入jQuery,也許你可以複製它的一部分(鏈接未測試,但jQuery擴展完美):https://gist.github.com/bentsai/3150936 – Kaddath

回答

-1

Object.assign()並不克隆的引用。對於深度克隆,您可以使用此技術JSON.parse(JSON.stringify(source))。所以,你的函數可以是這樣的:

function mergeDeep(target, source) { 
    let sourceClone = JSON.parse(JSON.stringify(source)); 
    Object.assign(target, sourceClone); 
} 

下面是修改樣本https://jsfiddle.net/q68z02pb/3/