js2-clone
js淺克隆和深克隆
1 、什麼是淺克隆?
只對外部物件進行克隆,不對此物件屬性的值如果也是一個物件,那麼就不進行克隆,如果陣列,只是複製陣列,陣列的內容沒變。
// 1、物件淺複製
var obj1 = { a: { x: 1 } };
var obj2 = Object.assign({}, obj1);
console.log(obj2);
obj1.a.x = 2;
console.log(obj2);
// 2、陣列淺複製
var arr = [{ x: 0 }, { x: 1 }];
var arr2 = arr.slice();
arr[1].x = 11;
console.log(arr2);
// 3、封裝整合
var clone = function (obj) {
if (!obj) return obj;
if (Array.isArray(obj)) {
return obj.slice();
} else {
return Object.assign({}, obj);
}
}
從例子可以看出,改變clone後的屬性可以影響原有物件,所以是淺clone
二、如何深度clone [deepClone]
2.1 方式,採用json.Stringfy序列化,然後json.pars反序列化
function deepClone1(target) {
var str = JSON.stringify(target);
var res = JSON.parse(str);
return res;
}
2.2 採用重組物件進行深度複製
function deepClone2(target) {
if((typeof target !== 'object') || !target) {
return target;
}
let newObj = Array.isArray(target) ? [] : {};
for (const key in target) {
if(newObj[key]) {return;}
newObj[key] = deepClone2(target[key]);
}
return newObj;
}
var obj1 = { a: { x: 1 } };
var obj2 = deepClone2(obj1);
obj1.a.x = 22;
console.log(obj1);
console.log(obj2);
2.3 最終版本(解決迴圈引用的問題)
function deepClone3(target) {
var temps = []; // 已經clone的物件
function mydeepClone(target) {
if((typeof target != 'object') || !target) {
return target;
}
for (let i = 0; i < array.length; i++) {
if(temps[i].target == target) {
return temp[i].copyTarget;
}
}
let obj = Array.isArray(target) ? [] : {};
Object.keys(target).forEach(key => {
if (obj[key]) { return; }
obj[key] = mydeepClone(target[key]);
});
return obj;
}
return mydeepClone(target);
}
var obj11 = { a: { x: 1 } };
var obj22 = deepClone2(obj11);
obj11.a.x = 22;
console.log(obj11); // 22
console.log(obj22); // 1