javascript中存儲對象都是存地址的。javascript
淺拷貝:淺拷貝是都指向同一塊內存區塊,淺拷貝共用同一內存地址,你改值我也變。若是拷貝的對象裏面的值是一個對象或者數組,它就是淺拷貝,拷貝的知識引用地址。 js的Object.assign,jquery的extend方法都是淺拷貝,通常的等號賦值也是淺拷貝 。html
上面vue裏面的兩個寫法也是淺拷貝,具體地址爲 https://cn.vuejs.org/v2/guide/list.html
vue
深拷貝:深拷貝則是另外開闢了一塊區域,深拷貝是互不影響,你改值我也不變。angular裏面的 angular.copy 是深拷貝。java
下面實例也能夠看出這一點:jquery
// 淺拷貝 const a = {t: 1, p: 'gg'}; const b = a; b.t = 3; console.log(a); // {t: 3, p: 'gg'} console.log(b); // {t: 3, p: 'gg'}
//深拷貝 const c = {t: 1, p: 'gg'}; const d = deepCopy(c); d.t = 3; console.log(c); // {t: 1, p: 'gg'} console.log(d); // {t: 3, p: 'gg'}
能夠明顯看出,淺拷貝在改變其中一個值時,會致使其餘也一塊兒改變,而深拷貝不會。數組
// Cloning an object var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); // { a: 1 }
// Merging objects var o1 = { a: 1 }; var o2 = { b: 2 }; var o3 = { c: 3 }; var obj = Object.assign(o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed. console.log(o2);//{b: 2} 源對象沒有變 console.log(o3);// {c: 3}
是否是很完美,又能夠clone又能夠merge。在我這種狀況下,我以爲個人代碼量又能夠減小了,好比:ide
const defaultOpt = { title: 'hello', name: 'oo', type: 'line' }; // 原來可能須要這樣 const opt1 = deepCopy(a); opt1.title = 'opt1'; opt1.type = 'bar'; opt1.extra = 'extra'; // 額外增長配置 // 如今只要這樣 const opt2 = Object.assign({}, a, { title: 'opt2', type: 'bar', extra: 'extra' });
注:它只對頂層屬性作了賦值,徹底沒有繼續作遞歸之類的把全部下一層的屬性作深拷貝。意思就是是拷貝一層,沒有拷貝多層。
一層 { a: 1, b: 2, } 多層 { a: 1, b: 2, c: { d: 4, e: { f: 6, g: 7 } } }
實現深拷貝,遍歷key
function deepClone(obj){ //判斷obj是否爲數組,若是是,初始化數組[],不然初始化對象{} let dcObj = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ //循環 for(key in obj){ //判斷對象是否有key屬性 if(obj.hasOwnProperty(key)){ //判斷ojb子元素是否爲對象,若是是,遞歸複製 if(obj[key]&&typeof obj[key] ==="object"){ dcObj[key] = deepClone(obj[key]); }else{ //若是不是,簡單複製 dcObj[key] = obj[key]; } } } } return dcObj; }; let t1 = { "a": 1, "b": 2, "c": { "d": 4, "e": { "f": 6, "g": 7 } } }; let t2=deepClone(t1); t1.a=6; console.log(t1); /* { "a": 6, "b": 2, "c": { "d": 4, "e": { "f": 6, "g": 7 } } } */ console.log(t2); //t1深拷貝給t2, b屬性的值仍是爲2,沒有改變,因此是深拷貝 /* { "a": 1, "b": 2, "c": { "d": 4, "e": { "f": 6, "g": 7 } } } */