淺拷貝只複製指向某個對象的指針,而不復制對象自己,新舊對象仍是共享同一塊內存。但深拷貝會另外創造一個如出一轍的對象,新對象跟原對象不共享內存,修改新對象不會改到原對象。
淺拷貝:賦值時,基本數據類型按值傳遞,對象按引用傳遞html
var a = 25; var b = a; b = 18; console.log(a);//25 console.log(b);//18 // b的修改並不會影響到a,由於它們是基本類型數據
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = obj1; obj2.b = 100; console.log(obj1); // { a: 10, b: 100, c: 30 } <-- b 被改到了 console.log(obj2); // { a: 10, b: 100, c: 30 } // obj2修改了b的值,同時obj1的b也會被修改,由於他們根本是同一個對象,這就是所謂的淺拷貝
深拷貝:函數
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c }; obj2.b = 100; console.log(obj1); // { a: 10, b: 20, c: 30 } <-- b 沒被改到 console.log(obj2); // { a: 10, b: 100, c: 30 }
淺拷貝的實現方式
(1)直接賦值,就是淺拷貝。對象直接複製,則新對象的改變也會修改到舊對象。
(2) Object.assign(target, ...sources)
指針
Object.assign
是ES6
的新函數。Object.assign()
方法能夠把任意多個的源對象自身的可枚舉屬性拷貝給目標對象,而後返回目標對象。可是Object.assign()
進行的是淺拷貝,拷貝的是屬性值。假如源對象的屬性值是一個指向對象的引用,它也只拷貝那個引用值。
var obj = { a: {a: "hello", b: 21} }; var initalObj = Object.assign({}, obj); initalObj.a.a = "changed"; console.log(obj.a.a); // "changed"
(3)對象展開符...
code
var obj = [{index: 1, msg: 'one'}, {index: 2, msg: 'two'}]; var obj2 = [...obj]; console.log(obj2); //[{index: 1, msg: 'one'}, {index: 2, msg: 'two'}] obj2.push({index: 3, msg: 'three'}); console.log(obj2); // [{index: 1, msg: 'one'}, {index: 2, msg: 'two'}, {index: 3, msg: 'three'}] console.log(obj); // [{index: 1, msg: 'one'}, {index: 2, msg: 'two'}] obj2[1].msg = 'two again'; console.log(obj2); // [{index: 1, msg: 'one'}, {index: 2, msg: 'two again'}, {index: 3, msg: 'three'}] console.log(obj); // [{index: 1, msg: 'one'}, {index: 2, msg: 'two again'}]
深拷貝的實現方式
(1)手動複製htm
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
(2)轉成JSON
再轉回來(只有能夠轉成JSON
格式的對象才能夠這樣用,像function
沒辦法轉成JSON)對象
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
(3)使用var newObj = Object.create(oldObj)
方法blog
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用對象致使死循環,如initalObj.a = initalObj的狀況 if(prop === obj) { continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : Object.create(prop); } else { obj[i] = prop; } } return obj; } var str = {}; var obj = { a: {a: "hello", b: 21} }; deepClone(obj, str);
【1】關於JavaScript
的淺拷貝和深拷貝three