方法一
老老實實敲代碼法(迭代法,適用於所有)
1.
function deepClone(obj) { let newObj = Array.isArray(obj) ? [] : {} if (obj && typeof obj === "object") { for (let key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = (obj && typeof obj[key] === 'object') ? deepClone(obj[key]) : obj[key]; } } } return newObj } const newObj = deepClone(oldObj));
2.自己內部資料
function DeepClone(source) {
// 判斷目標是數組還是對象
const targetObj = source.constructor === Array ? [] : {};
for (let key in source) {
if (source.hasOwnProperty(key)) {
// 如果是對象就遞歸
if (source[key] && typeof source[key] === 'object') {
targetObj[key] = source[key].constructor === Array ? [] : {}
targetObj[key] = DeepClone(source[key])
} else {
targetObj[key] = source[key]
}
}
}
return targetObj
}
方法二
利用JSON.stringify 將js對象序列化(JSON字符串),再使用JSON.parse來反序列化(還原)js對象
const newObj = JSON.parse(JSON.stringify(oldObj));
缺點:
- 如果obj里面有時間對象,則JSON.stringify后再JSON.parse的結果,時間將只是字符串的形式。而不是時間對象;
- 如果obj里有RegExp、Error對象,則序列化的結果將只得到空對象;
- 如果obj里有function,Symbol 類型,undefined,則序列化的結果會把函數或 undefined丟失;
- 如果obj里有NaN、Infinity和-Infinity,則序列化的結果會變成null
- JSON.stringify()只能序列化對象的可枚舉的自有屬性,例如 如果obj中的對象是有構造函數生成的, 則使用JSON.parse(JSON.stringify(obj))深拷貝后,會丟棄對象的constructor;
方法三
const newObj = Object.assign([],oldObj);
缺點
- Object.assign只對頂層屬性做了賦值,完全沒有繼續做遞歸之類的把所有下一層的屬性做深拷貝。
簡而言之,第一層實現了深度拷貝,后續層次還是淺拷貝