2015-07-05 263 views
0

假設我有一個可以是任意Javascript對象的源對象,它可以具有屬於它們自己的對象(或數組或函數)嵌套到任何級別的屬性。Javascript - 將特定對象從一個對象複製到另一個新對象

我想執行此對象的深層副本到一個新的目標對象。不過,我只想複製特定的白名單屬性。這些可以位於源對象中的任何級別。

到目前爲止,我已經手動將源對象中的白名單屬性分配給目標對象。這看起來不是很優雅,也不是可重用的。你可以給我一些關於使用更優雅和可重用的方法來實現這一點的指導嗎?

+1

你能給一個對象的例子,以及你目前如何做它(實際的代碼)? – Xotic750

+0

Porque沒有遞歸?就像http://stackoverflow.com/questions/31215369/javascript-how-to-filter-arrays-mathcing-a-keyword/31215528#31215528,除了按名稱複製某些屬性 – Jan

回答

2

這應該做你正在尋找的東西,包括循環引用。

編輯:請記住,這將變得越來越慢,對於有很多循環引用裏面的對象!查看引用是否被查看只是一個簡單的掃描。

var util = require('util') 


var propertiesToCopy = { 
    'a' : true, 
    'b' : true, 
    'c' : true, 
    'd' : true, 
    'e' : true, 
    'f' : true, 
    'p1': true, 
    'p2': true, 
    'g' : true 
}; 

var obj; 

obj = { 
    p2 : { 
     a : 1, 
     b : 2, 
     c : {}, 
     d : { 
      f : 2 
     } 
    }, 
    p3 : 'hello' 
}; 

// circular 
obj.p1 = obj; 
obj.p2.d.e = obj; 

// sub-circular 
obj.p2.g = obj.p2.c; 

function getNewObjectFromObjects(obj, objects) { 
    for (var i = 0; i < objects.length; i++) { 
     if (obj === objects[i].old) return objects[i].new; 
    } 
    return false; 
} 

function whiteListedCopy(obj, whitelist, root, newRoot, objects) { 
    var cloned = {}; 
    var keys = Object.keys(obj); 
    root = root || obj; 
    newRoot = newRoot || cloned; 
    objects = objects || [ {'old' : root, 'new': newRoot} ]; 
    keys.forEach(function(val) { 
     if (whitelist[val] === true) { 
      if (typeof(obj[val]) === typeof({}) || 
       typeof(obj[val]) === typeof([])) { 
       var reference = getNewObjectFromObjects(obj[val], objects); 
       if (reference === false) { 
       cloned[val] = whiteListedCopy(obj[val], whitelist, root, newRoot, objects);           
        objects.push({ 'old' : obj[val], 'new': cloned[val]}); 
       } else { 
        cloned[val] = reference; 
       } 
      } else { 
       cloned[val] = obj[val]; 
      } 
     } 
    }); 
    return cloned; 
} 

var clonedObject = whiteListedCopy(obj, propertiesToCopy); 

console.log(util.inspect(clonedObject)); 

console.log('assert c and g are same reference:', clonedObject.p2.g === clonedObject.p2.c); 
console.log('assert p1 is circular:', clonedObject === clonedObject.p1); 
+1

這很好。感謝您花時間實施此解決方案。 –

相關問題