理解深拷貝和淺拷貝之前先了解下js中的基本型別和引用型別
1、基本型別:
在js中,資料的基本型別undefined,null,string,number,boolean,在變數中賦的實際值,基本型別就是簡單的資料段。
基本型別的值是不可以改變的
var a = 1;
var b = a;
a++;
console.log(a); //2
console.log(b); //1
這裡a和b是獨立的,當改變a或b,其另外乙個值不會隨之改變
2、引用型別:
在js中,資料的引用型別object,array,regexp,date,function,在變數中賦的實際值
引用型別的值是可以改變的
var arr = [1,2,3,4,5];
var arr2 = arr;
arr[0] = 2;
console.log(arr); //[2、2、3、4、5]
console.log(arr2);//[2、2、3、4、5]
這裡在改變arr[0]中的值後,arr2資料也跟著改變,引用型別在賦值的時候(arr2=arr),其實在棧記憶體中新增了arr2,但是堆記憶體中還是[1,2,3,4,5],通俗點講就是引用型別賦值並非真正意義上的資料賦值,而是在棧記憶體中新增乙個指標,還是指向堆記憶體中的[1,2,3,4,5],只新增棧記憶體的指標
好,到這裡我們在討論深拷貝和淺拷貝,深拷貝顧名思義是在資料是相互獨立的,改資料而另乙個不受影響,淺拷貝則是資料會隨之改變而改變。
這麼一看,基本型別不正好是嘛,資料都是相互獨立的,乍看好像還真是的。
但是,但是,我們所說的深拷貝必須要在複雜的object型別下,基本型別裡沒有object,那麼只能是引用型別。
再來看個例子:
var arr3 = [[1,2],3,4,5];
var arr4 = arr3;
arr3[0][1] = 3;
console.log(arr3); //[[1,3],3,4,5]
console.log(arr4); //[[1,3],3,4,5]
明明改了arr3,為何arr4也改了,這不是我想要的,那如何獨立呢,你會發現使用什麼for迴圈,slice,concat是根本不管用的,網上有其他的坑,在此我就不多說了,直接說解決辦法
方法1、json
利用json.stringify和json.parse
var arr3 = [[1,2],3,4,5];
var arr4 = json.parse(json.stringify(arr3));
arr3[0][1] = 3;
console.log(arr3); //[[1,3],3,4,5]
console.log(arr4); //[[1,2],3,4,5]
但是這種方法有個小弊端,就是值不能為undefined或null,最好對資料提前判斷
方法2、jq $.extend
$.extend([deep],target,object1[,objextn]); //deep 值為true或false,true為深拷貝,false為淺拷貝。target 目標物件,其他物件的成員屬性將被附加到該物件上 object1/objextn 是需要被操作的物件,可以是多個,這裡是例子中的arr3
var arr3 = [[1,2],3,4,5];
var arr4 = $.extend(true,,arr3);
arr3[0][1] = 3;
console.log(arr3); //[[1,3],3,4,5]
console.log(arr4); //[[1,2],3,4,5]
以上就是介紹的兩種方法
理解「淺拷貝」和「深拷貝」
淺拷貝 將原物件 原陣列 的 引用 直接賦給新物件 新陣列 新物件 新陣列 是原物件 原陣列 的乙個引用。如果改變這個新物件 新陣列 原物件 原陣列 就會改變。深拷貝 將原物件的各項屬性的 值 陣列的所有元素 都拷貝給新物件 新陣列 是拷貝的 值 而不是 引用 為什麼要使用深拷貝?希望改變新物件 新...
JS深拷貝和淺拷貝
js中物件分為基本型別和復合 引用 型別,基本型別存放在棧記憶體,復合 引用 型別存放在堆記憶體中 堆記憶體中用於存放由new建立的物件,棧記憶體存放一些基本型別的變數和物件的引用變數 對於簡單變數,記憶體小,直接複製不會發生引用 var a 123 var b a a 123456 console...
JS淺拷貝和深拷貝
1.淺拷貝 copy var obj1 物件存放於堆記憶體中,物件中的鍵值對,值可以為物件,可以為陣列.var obj2 obj1 物件,陣列之間只有引用賦值 obj2.name 撒哈哈 當改動物件obj2的時候,obj1的key對應的value也會更改這是淺拷貝 深拷貝 var obj1 var ...