js 陣列的淺拷貝和深拷貝

小明明同學發表於2021-03-09

1.背景介紹

  javascript分原始型別與引用型別。Array是引用型別,直接用“=”號賦值的話,只是把源陣列的地址(或叫指標)賦值給目的陣列,指向的是同一個記憶體地址,其中一個改變另一個也會改變。並沒有實現陣列的資料的拷貝。這種方式的實現屬於淺拷貝。

  深拷貝是開闢新的儲存空間,兩個物件對應兩個不同的地址,修改一個物件的屬性,不會改變另一個物件的屬性。

2.使用方法

陣列淺拷貝:

var arr1 = [1, 2, 3, 4];
var arr2 = arr1; 
arr1[0] = 6;                //陣列是用堆去儲存的,相等的時候只是把存放的地址拷貝過去了,兩個指向了同一個地址,所以在改變其中一個的值,其他的也跟著改變了
console.log(arr2[0]);       //輸出結果為6
console.log(arr1);        //[6, 2, 3, 4]
console.log(arr2);        //[6, 2, 3, 4]

陣列深拷貝:

1.JSON.stringify和JSON.parse方法

var arr1 = [1, 2, 3, 4];
var arr2 = JSON.parse(JSON.stringify(arr1)) //先將陣列轉為字串,然後轉成js物件
arr1[0] = 6; 
console.log(arr2[0]);       //輸出結果為1
console.log(arr1);        //[6, 2, 3, 4]
console.log(arr2);        //[1, 2, 3, 4]

2.slice方法

var arr1 = [1, 2, 3, 4];
var arr2 = arr1.slice(0);   //從0開始到末尾擷取陣列,然後返回一個新的陣列
arr1[0] = 6; 
console.log(arr2[0]);       //輸出結果為1
console.log(arr1);        //[6, 2, 3, 4]
console.log(arr2);        //[1, 2, 3, 4]

3.concat方法

var arr1 = [1, 2, 3, 4];
var arr2 = arr1.concat();   //連線陣列,如果連線的是一個空,那麼也是返回了新的本身的陣列
arr1[0] = 6; 
console.log(arr2[0]);       //輸出結果為1
console.log(arr1);        //[6, 2, 3, 4]
console.log(arr2);        //[1, 2, 3, 4]

4.map方法

var arr1 = [1, 2, 3, 4]; 
var arr2 = arr1.map(function(value){
     return value;
})                          //使用map方法遍歷陣列然後返回新的陣列,裡面的值不變
arr1[0] = 6;   
console.log(arr2[0])        //輸出結果為1
console.log(arr1);          //[6, 2, 3, 4]
console.log(arr2);          //[1, 2, 3, 4]

5.ES6語法

var arr1 = [1, 2, 3, 4];
var [ ...arr2 ] = arr1;     //ES6擴充套件運算子實現陣列的深拷貝
arr1[0] = 6; 
console.log(arr2[0]);       //輸出結果為1
console.log(arr1);        //[6, 2, 3, 4]
console.log(arr2);        //[1, 2, 3, 4]

6.用for迴圈遍歷複製

var arr1 = [1, 2, 3, 4];
var arr2 = [];
for(i=0;i<arr1.length;i++){
  arr2.push(arr1[i])
}
arr1[0] = 6; 
console.log(arr2[0]);       //輸出結果為1
console.log(arr1);        //[6, 2, 3, 4]
console.log(arr2);        //[1, 2, 3, 4]

 

 

簡單來說,深拷貝主要是將另一個物件的屬性值拷貝過來之後,另一個物件的屬性值並不受到影響,因為此時它自己在堆中開闢了自己的記憶體區域,不受外界干擾。
淺拷貝主要拷貝的是物件的引用值,當改變物件的值,另一個物件的值也會發生變化。

那具體使用情況該使用淺拷貝還是深拷貝呢,沒有一成不變的規則,一切都取決於具體需求~

 

相關文章