天天看點

js中的數組 兩個數組值相同時,一個數組改變 另一個數組跟着改變的原因。兩個相等的數組,修改其中一個數組怎麼做到不改變另外一個數組?論深度拷貝的重要性

示例:

現在有兩個數組:

let arrA = [1, 2, 3];
let arrB = arrA;
console.log(arrA); // [1, 2, 3]
console.log(arrB); // [1, 2, 3]
           
  1. 當數組arrA改變時,數組arrB也會改變:
arrA[0] = 10; 
console.log(arrA); // [10, 2, 3]
console.log(arrB); // [10, 2, 3]
           
  1. 當數組arrB改變時,數組arrA也會改變:
arrB.push(4);
console.log(arrA); // [1, 2, 3, 4] 
console.log(arrB); // [1, 2, 3, 4] 
           

導緻兩個數組互相影響的原因:

js中array是引用類型,也就是arrA和arrB的原資料存儲位址是一樣的,arrA和arrB都是對原資料的引用,是以修改其中一個,另一個也會改變。

這就好像是現在有一個房間,兩扇門,AB兩人分别從不同的門進去所看到的的房間是一樣的,此時A拿走一個蘋果,B會看到房間裡少了一個蘋果;B從外面帶了一瓶飲料回到房間,A也會看到這個房間多了一瓶飲料。

那麼上面兩個相等的數組,修改其中一個怎麼做到不改變另外一個呢?也就是說僅僅是數組arrA指派給數組arrB,而不是把引用賦給它

方案1:

concat()用于連接配接兩個或多個數組。(該方法不會改變現有的數組,而僅僅會傳回被連接配接數組的一個副本)

let arrA = [1, 2, 3];
let arrB = [].concat(arrA);
console.log(arrA,arrB);  // [1, 2, 3],[1, 2, 3]
           

當數組arrA改變, 數組arrB不變時:

arrA.splice(0,1);
console.log(arrA,arrB);  // [2, 3],[1, 2, 3]
           

當數組arrB改變, 數組arrA不變時:

arrB[0] = 0;
console.log(arrA,arrB);   // [1, 2, 3],[0, 2, 3]
           

方案2:

先JSON.stringify( ) 後 JSON.parse( )

let arrA = [1, 2, 3];
let arrB = JSON.parse(JSON.stringify(arrA));  
console.log(arrB); // [1, 2, 3]
           
  1. 當數組 arrB.pop()
console.log(arrA,arrB);   // [1, 2,3],[1, 2]
           
  1. 當數組 arrA.shift()
console.log(arrA,arrB);   // [ 2,3],[1, 2,3]
           

方案3:

jQuery的extend方法

let a = [1,2,3];
let b = $.extend(true,[],a)
b[0]++  
console.log(a,b); // [1,2,3],[2,2,3]
           

方案4:

Object.assign()方法 或者 […arr]

let a = [1,2,3];
let b = Object.assign([],a)   //或者 let b = [...a]  
b[0]++ 
console.log(a,b); // [1,2,3],[2,2,3]
           

但是需要注意的是:*如果是對象數組,即使是用方案1的concat、方案4的**Object.assign()或者[…arr]*指派也是會互相影響的:

let a=[{name:'zhangsan',age:20}]
let b = Object.assign([],a)   // 或者 let b = [...a]  或者 let b = [].concat(a) 
b[0].age=25;   
console.log()a,b; // [{name:'zhangsan',age:25}],[{name:'zhangsan',age:25}] 
           

此時用方案3的先JSON.stringify( ) 後 JSON.parse( )

繼續閱讀