JavaScript有兩種數據類型,基礎數據類型和引用數據類型。基礎數據類型都是按值訪問的,我們可以直接操作保存在變數中的實際的值。而引用類型如Array,我們不能直接操作對象的堆記憶體空間。引用類型的值都是按引用訪問的,即保存在變數對象中的一個地址,該地址與堆記憶體的實際值相關聯。 一、深拷貝和淺拷貝 ...
JavaScript有兩種數據類型,基礎數據類型和引用數據類型。基礎數據類型都是按值訪問的,我們可以直接操作保存在變數中的實際的值。而引用類型如Array,我們不能直接操作對象的堆記憶體空間。引用類型的值都是按引用訪問的,即保存在變數對象中的一個地址,該地址與堆記憶體的實際值相關聯。
一、深拷貝和淺拷貝的區別
淺拷貝(shallow copy):只複製指向某個對象的指針,而不複製對象本身,新舊對象共用一塊記憶體;
深拷貝(deep copy):複製並創建一個一摸一樣的對象,不共用記憶體,修改新對象,舊對象保持不變。
var a = 25;
var b = a;
b = 10;
console.log(a);//25
console.log(b);//10
//淺拷貝
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = obj1;
obj2.b = 40;
console.log(obj1);// { a: 10, b: 40, c: 30 }
console.log(obj2);// { a: 10, b: 40, c: 30 }
//深拷貝
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
obj2.b = 40;
console.log(obj1);// { a: 10, b: 20, c: 30 }
console.log(obj2);// { a: 10, b: 40, c: 30 }
二、淺拷貝的實現
var json1 = {"a":"name","arr1":[1,2,3]}
function copy(obj1) {
var obj2 = {};
for (var i in obj1) {
obj2[i] = obj1[i];
}
return obj2;
}
var json2 = copy(json1);
json1.arr1.push(4);
alert(json1.arr1); //1234
alert(json2.arr1) //1234
三、深拷貝的實現
1、Object.assign()
let foo = {
a: 1,
b: 2,
c: {
d: 1,
}
}
let bar = {};
Object.assign(bar, foo);
foo.a++;
foo.a === 2 //true
bar.a === 1 //true
foo.c.d++;
foo.c.d === 2 //true
bar.c.d === 1 //false
bar.c.d === 2 //true
Object.assign()
是一種可以對非嵌套對象進行深拷貝的方法,如果對象中出現嵌套情況,那麼其對被嵌套對象的行為就成了普通的淺拷貝。
2、轉成JSON
用JSON.stringify把對象轉成字元串,再用JSON.parse把字元串轉成新的對象。
var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.body.a = 20;
console.log(obj1); // { body: { a: 10 } }
console.log(obj2); // { body: { a: 20 } }
console.log(obj1 === obj2); // false
console.log(obj1.body === obj2.body); // false
但這種方法的缺陷是會破壞原型鏈,並且無法拷貝屬性值為function的屬性
3、遞歸
採用遞歸的方法去複製拷貝對象
var json1={"name":"shauna","age":18,"arr1":[1,2,3,4,5],"string":'got7',"arr2":[1,2,3,4,5],"arr3":[{"name1":"shauna"},{"job":"web"}]};
var json2={};
function copy(obj1,obj2){
var obj2=obj2||{};
for(var name in obj1){
if(typeof obj1[name] === "object"){
obj2[name]= (obj1[name].constructor===Array)?[]:{};
copy(obj1[name],obj2[name]);
}else{
obj2[name]=obj1[name];
}
}
return obj2;
}
json2=copy(json1,json2)
json1.arr1.push(6);
alert(json1.arr1); //123456
alert(json2.arr1); //12345