2016-01-20 103 views
0

我一直在閱讀關於克隆和每個人似乎都在使用一些複雜的代碼。我想我可能做錯了,但它似乎正在工作,並且在更改「克隆」對象屬性的值時,我的主對象不會更改。我是克隆/複製javascript對象。我做對了嗎?

var clonedObject ={}; 
//randomItem is main object, which I want to clone 
for (var key in randomItem) { 
    if (randomItem.hasOwnProperty(key)) { 
     clonedObject[key] = {}; 
     clonedObject[key] = randomItem[key]; 
    } 
}; 
return clonedObject; 

它適合我,請告訴我,如果有什麼問題嗎? 我很困惑,因爲與其他職位相比,這似乎太容易了(其中一些人是7歲)。感謝

+2

你總是可以只是做:'VAR克隆= JSON.parse(JSON.stringify(originalObj))' – tymeJV

+1

是它能夠做到這一點,爲什麼ü困惑正確的方式? –

+3

@tymeJV - 只有當這些值都是原始的。它會打破你把複雜的物體放在那裏的時刻。 – Quentin

回答

1

下面是一個簡單的例子,你可以看到你的代碼嵌套對象的行爲相比,真正的深克隆:

var x = {a:{a:1}}; 
 

 
function update() { 
 
    document.getElementById('x').textContent = JSON.stringify(x); 
 
    document.getElementById('y').textContent = JSON.stringify(y); 
 
    document.getElementById('z').textContent = JSON.stringify(z); 
 
} 
 

 
// This is your code 
 
function yourClone (randomItem) { 
 
    var clonedObject ={}; 
 
    for (var key in randomItem) { 
 
    if (randomItem.hasOwnProperty(key)) { 
 
     clonedObject[key] = {}; 
 
     clonedObject[key] = randomItem[key]; 
 
    } 
 
    }; 
 
    return clonedObject; 
 
} 
 

 
// This is a real deep clone taken from http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object 
 
function deepClone (obj) { 
 
    var copy; 
 

 
    // Handle the 3 simple types, and null or undefined 
 
    if (null == obj || "object" != typeof obj) return obj; 
 

 
    // Handle Date 
 
    if (obj instanceof Date) { 
 
    copy = new Date(); 
 
    copy.setTime(obj.getTime()); 
 
    return copy; 
 
    } 
 

 
    // Handle Array 
 
    if (obj instanceof Array) { 
 
    copy = []; 
 
    for (var i = 0, len = obj.length; i < len; i++) { 
 
     copy[i] = deepClone(obj[i]); 
 
    } 
 
    return copy; 
 
    } 
 

 
    // Handle Object 
 
    if (obj instanceof Object) { 
 
    copy = {}; 
 
    for (var attr in obj) { 
 
     if (obj.hasOwnProperty(attr)) copy[attr] = deepClone(obj[attr]); 
 
    } 
 
    return copy; 
 
    } 
 

 
    throw new Error("Unable to copy obj! Its type isn't supported."); 
 
} 
 

 

 
function inc() { 
 
    x.a.a++; 
 
    update(); 
 
}
<body onload="y=yourClone(x);z=deepClone(x);update()"> 
 
    x: <span id="x"></span><br/> 
 
    y: <span id="y"></span> &lt;- your clone from 'x'<br/> 
 
    z: <span id="z"></span> &lt;- real deep clone from 'x'<br/><br/> 
 
    <button id="inc" onclick="inc()">Increment nested element in x</button> 
 
</body>

當你複製一些變量的值插入到另一根據數據類型的不同,您將複製該值本身(數字和文本)或者只是對數據(日期,數組和對象)的引用。處理引用時,您需要遞歸地進入下一個級別,並將所有值複製到新對象中以創建新實例。

+0

嘿,你的代碼片段不適合我。我理解或多或少的深層/淺層複製。如果我有嵌套的對象,我需要做一個深層複製。這是否意味着,上面的代碼(深層複製)將複製所有級別上的所有嵌套對象?例如:'var myObj = {a:{b:{c:{d:{}}}}}'它會以完全相同的方式複製它嗎?它也複製屬性內部的函數嗎?這也不錯:) – Mariusz

+0

我編輯它使用'textContent'而不是'innerText',所以它可以跨瀏覽器使用。是的,上面的代碼將遞歸地複製對象的所有級別,包括函數:) –

+0

謝謝,這將是有用的:) – Mariusz