陣列賦值問題涉及到拷貝、堆疊空間、基本資料型別和引用資料型別的差異。(自行了解)
var arrA = [1,2,3,4,5];
var arrB = arrA;
// 把B陣列值重置成0;
arrB.fill(0);
console.log(arrA);
console.log(arrB);
輸出結果是:arrA = [0,0,0,0,0], arrB = [0,0,0,0,0]
arrB的修改的同時也修改了arrA的值。
可採用淺拷貝和深拷貝解決問題:
- 淺拷貝子物件是基礎資料型別的修改不受影響,子物件是引用資料型別仍然會受影響
- 深拷貝,子物件是引用資料型別也不受影響。
var arrA = [1, 2, 3, 4, 5];
var arrB = arrA.slice(0, 5);
// 把B陣列值重置成0;
arrB.fill(0);
console.log(arrA);
console.log(arrB);
輸出結果是:arrA = [1, 2, 3, 4, 5], arrB = [0, 0, 0, 0, 0];
var arrA = [1, 2, [3, 4], 5, 6];
var arrB = arrA.slice(0, 5);
// 把B[2]陣列值重置成0;
for (var i = 0; i < arrB.length; i++) {
if (arrB[i].length > 0) {
arrB[i].fill(0);
}
}
console.log(arrA);
console.log(arrB);
輸出結果是:arrA = [1, 2, [0,0], 5, 6], arrB = [1, 2, [0,0], 5, 6];
親測: 用arrA.slice()/arrA.concat()/[…arrA]/Array.from(arrA)/Array.prototype.push.apply(arrB, arrA)/ arrA.map(function(item){return item;});等方法進行陣列複製都是淺拷貝。
(Object.assign({}, objA)物件淺拷貝)
var arrA = [1, 2, [3, 4], 5, 6];
var arrB = JSON.parse(JSON.stringify(arrA));
// 把B陣列值重置成0;
arrB[2].fill(0);
console.log(arrA);
console.log(arrB);
輸出結果是:arrA = [1, 2, [3, 4], 5, 6], arrB = [1, 2, [0, 0], 5, 6];
var arrA = [1, undefined, [3, 4], 5, 6];
var arrB = JSON.parse(JSON.stringify(arrA));
// 把B陣列值重置成0;
arrB[2].fill(0);
console.log(arrA);
console.log(arrB);
輸出結果是:arrA = [1, undefined, [3, 4], 5, 6], arrB = [1, null, [0, 0], 5, 6];
親測: JSON.parse(JSON.stringify(arrA))JSON轉換是深拷貝,但是如果值為undefined會被轉為null。
let arrA = [1, 2, [3, 4], 5, 6];
let arrB = _.cloneDeepWith(arrA);
// 把B陣列值重置成0;
arrB[2].fill(0);
console.log(arrA);
console.log(arrB);
輸出結果是:arrA = [1, undefined, [3, 4], 5, 6], arrB = [1, null, [0, 0], 5, 6];
可使用第三方庫如lodash封裝的方法。