深拷貝和淺拷貝原理
阿新 • • 發佈:2020-08-24
基礎資料型別:
string、number、null、undefined、boolean、symbol
引用資料型別:
函式、物件、陣列
產生原因:
基本型別是按值訪問的,引用型別是按引用訪問
1、基本型別的儲存是放在棧區的
2、引用型別的儲存是放在堆記憶體中的
當引用型別進行賦值的時候,JavaScript不允許直接訪問記憶體中的位置,也不能直接操作物件中的記憶體空間。操作物件是直接操作物件的引用,而不是整個物件,所以就會出現深拷貝、淺拷貝的問題
淺拷貝只複製指向某個物件的指標,而不復制物件本身,相當於是新建了一個物件,該物件複製了原物件的指標,新舊物件還是共用一個記憶體塊,
深拷貝是新建一個一模一樣的物件,該物件與原物件不共享記憶體,修改新物件也不會影響原物件
淺拷貝實現方式:
1、物件使用Object.assign(target, source)方法
let testDeepObj2 = Object.assign({},testDeepObj1);
testDeepObj1物件中有引用型別的話,就是淺拷貝
2、陣列使用slice()、concat()方法
var arr = ['jack',25,{hobby:'tennise'}]; let arr1 = arr.slice() arr1[2].hobby='rose' arr1[0]='rose' console.log( arr[2].hobby) //rose console.log( arr[0]) //jack
深拷貝實現方式:
1.JSON.parse(JSON.stringify()),這種方式的缺點是當物件裡面有函式的話,深拷貝後,函式會消失
let arr1 = JSON.parse(JSON.stringify(arr))
2、手寫遞迴函式實現深拷貝
function copy(obj){ let newobj = null; //宣告一個變數用來儲存拷貝之後的內容 //判斷資料型別是否是複雜型別,如果是則呼叫自己,再次迴圈,如果不是,直接賦值即可, //由於null不可以迴圈但型別又是object,所以這個需要對null進行判斷 if(typeof(obj) == 'object' && obj !== null){ //宣告一個變數用以儲存拷貝出來的值,根據引數的具體資料型別宣告不同的型別來儲存 newobj = obj instanceof Array? [] : {}; //迴圈obj 中的每一項,如果裡面還有複雜資料型別,則直接利用遞迴再次呼叫copy函式 for(var i in obj){ newobj[i] = copy(obj[i]) } }else{ newobj = obj } console.log('77',newobj) return newobj; //函式必須有返回值,否則結構為undefined }
參考文獻:https://blog.csdn.net/qq_34645412/article/details/106327826