2016-01-20 88 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