在JavaScript中,數據類型分爲兩大類:基本數據類型和複雜數據類型。基本數據類型包括Number、Boolean、String、Null、String),而複雜數據類型包括Object、Function、Array。spa
而對於基本數據類型來講,複製一個變量值,本質上就是copy了這個變量。一個變量值的修改,不會影響到另一個變量。指針
let val = 123; let copy = val; console.log(copy); //123 val = 456; //修改val的值對copy的值不產生影響 console.log(copy); //123
而對於複雜數據類型來講,同基本數據類型實現的不太相同。對於複雜數據類型的複製,要注意的是,變量名只是指向這個對象的指針。當咱們將保存對象的一個變量賦值給另外一個變量時,實際上覆制的是這個指針,而兩個變量都指向都一個對象。所以,一個對象的修改,會影響到另一個對象。code
// obj只是指向對象的指針 let obj = { character: 'peaceful' }; //copy變量複製了這個指針,指向同一個對象 let copy = obj; console.log(copy); //{character: 'peaceful'} obj.character = 'lovely'; console.log(copy); //{character: 'lovely'}
在JavaScript中,拷貝對象分爲兩種方式,淺拷貝和深拷貝。對象
淺拷貝指兩個不一樣的變量存的是同一個對象的地址,即兩個變量指向同一塊內存區域;深拷貝則是從新分配了一塊內存區域來存儲複製後的對象,兩個變量存的是真正的兩個互不影響的變量。blog
let objA = { name: '對象A', content: '我是A' }; let copyA = objA; console.log(objA.name); // ==> "對象A" console.log(copyA.name); // ==> "對象A"
如此即獲得了objA的一份淺拷貝copyA,因爲指向的是同一個對象,所以在修改objA的同時也是修改了copyA,反之亦然。遞歸
Object.assign(target, …sources) ip
若是咱們把它的第一個參數target設置爲一個空對象 {},同時保證剩餘的源對象sources中的屬性類型不包含引用類型,則該方法的返回值就是一個與源對象相同的但並不在同一塊內存空間另外一個對象,即得到了源對象的深拷貝。可是,若是源對象的屬性中包含某個對象,也就是這個屬性的值指向某個對象,就像下面這樣:內存
var obj = { name: 'obj name', content: { a: 1, b: 2 } };
則使用 Object.assign({}, obj) 時,返回的目標對象中的content屬性與源對象obj中的content屬性指向的同一塊內存區域,即對obj下的content屬性進行了淺拷貝。所以針對深拷貝,須要使用其餘方法,好比本身實現一個深拷貝的方法,或者使用 JSON.parse(JSON.stringify(obj))字符串
另外一種淺拷貝 ...操做符:get
let arr = {a:1,b:2} let arr2 = {...arr} arr2.a = 2 console.log(arr.a)//1 console.log(arr2.a)//2
我認爲對於對象來講最簡單的深拷貝方法就是轉成字符串再解析
var obj = {a:1,b:2} var newObj = JSON.parse(JSON.stringify(obj)); newObj.a=3; console.log(obj);
另一種深拷貝方法:遞歸遍歷
var obj = {a:{b:10}}; function deepCopy(obj){ if ( typeof obj != 'object' ){ // ( obj instanceof Object || obj instanceof Array ) return obj; } var newobj = {}; for ( var attr in obj) { newobj[attr] = deepCopy(obj[attr]); } return newobj; } var obj2 = deepCopy(obj); obj2.a.b = 20; alert(obj.a.b); //10